首页 新闻 会员 周边

VUE的v-for中深入响应式原理的问题

0
悬赏园豆:100 [已解决问题] 解决于 2021-02-09 19:05

开发Vue的一个组件遇到下面的问题:

<div v-for="item in items" :key="item.id">
    <div>{{ item.content.name }}</div>
    <img v-if="item.content.src" :src="item.content.src" alt="loading" />
    <!--目前这个src还不知道 -->
</div>

在该组件的script中:

export default {
    watch:{
         items: function(new_val){
             console.log( new_val )  ;
         }
    },
    computed:{
        items() {
             return this.$store.state.items
        }
     }
}

上面的组件用到了vuex中的items, 这个items的值会进行异步修改. 也就是说, 首次渲染的时候img没有src属性, 图片不会加载; 随后当异步消息到达vuex并修改v-for的遍历对象items后, 我想让这个已经被render的对象更新src, 进而显示图片.

可是看了官方文档[https://cn.vuejs.org/v2/guide/reactivity.html#对于数组], 试了试对items修改时, 使用splice(index, 1, new_val)方法, 结果可以让上面的组件watch到items中src的变化, 但是!!!⚠️ , 真正的问题是v-for渲染不到items的变化, 真实的DOM中src并没有改变, 这就很让人头疼, 不知道哪位大神可以解答一下, 感谢🙏

Bravo_Jack的主页 Bravo_Jack | 初学一级 | 园豆:64
提问于:2020-11-26 10:56

你可能需要把 store 中的代码放出来看看

by.Genesis 3年前
< >
分享
最佳答案
0

watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

收获园豆:100
kitty20180903suzhou | 菜鸟二级 |园豆:314 | 2020-11-26 18:32
其他回答(7)
0

items打印出来看看是不是为空了,还有首次渲染应该设置一个默认图片的。。。

刘下来 | 园豆:919 (小虾三级) | 2020-11-26 11:15

v-if里面应该是判断语句,只有为true时,img标签才会显示出来

支持(0) 反对(0) 刘下来 | 园豆:919 (小虾三级) | 2020-11-26 11:17

感谢回答,
items是一个非空的Array: [{name: 'pic1', src:'xxxxxx1'},{name: 'pic2', src:'xxxxxx2'}]

我据这个例子是随便写的一个组件, 真实的组件没有写出来, 因为有很多不想管的内容

支持(0) 反对(0) Bravo_Jack | 园豆:64 (初学一级) | 2020-11-26 11:32

@Bravo_Jack: 你的数组里没有content?那你item.content.src.....

支持(0) 反对(0) 刘下来 | 园豆:919 (小虾三级) | 2020-11-26 12:01

@学会乐观: 不好意思, 随便写的例子写的不严谨

[ {name: 'pic1', content { 
        src:'xxxxxx1'
        others: 'xxx'
  }},
  {name: 'pic2', content { 
        src:'xxxxxx1'
        others: 'xxx'
  }}
]
支持(0) 反对(0) Bravo_Jack | 园豆:64 (初学一级) | 2020-11-26 12:23
0

你使用的是对象(item)属性的属性, 把属性的属性往上层移动下试下,变成对象的属性试下

大志若愚 | 园豆:2138 (老鸟四级) | 2020-11-26 14:11
0

vm.$set 试试用这个来更新。 新加的属性,
2:或者默认加上src 属性 值为空。异步的时候在来修改 提前申明属性

s_p | 园豆:138 (初学一级) | 2020-11-26 14:48
0

可以试下,items.push

Jack_F | 园豆:211 (菜鸟二级) | 2020-11-26 15:55
0

如果是渲染出来看不到的话,就在样式表中加上line-height这一句,设置下行高就好了,如果不是的话就不知道了,也是刚入门

藤井の树 | 园豆:180 (初学一级) | 2020-11-27 10:21
0
czd890 | 园豆:14412 (专家六级) | 2020-11-27 12:58
0

用 vm.$set , deep watch 太脏。另外 vue3 就不会有这个问题了,vue3 以前受限于 defineProperty API。https://cn.vuejs.org/v2/api/#Vue-set

guangzan | 园豆:246 (菜鸟二级) | 2021-07-18 16:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册