程志辉博客 - 一个伪文艺青年
贵在坚持,难在坚持,成在坚持!
程志辉

问题

在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向数组对象中添加新的属性,如果直接更新此属性的值,是不会更新视图的。

根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

实现

HTML部分

<div id="app">
    <ul>
        <li v-for="value in obj" :key="value">
            {{value}}
        </li>
    </ul>

    <button @click="addObjB">添加obj.b</button>
</div>

JS部分

data() {
    return {
        obj: {
            a: "obj.a"
        }
    }
},
methods: {
    addObjB() {
        // 默认情况下
        // this.obj.b = "obj.b"

        // 第一种解决方法
        // let obj = {
        //     a: "obj.a",
        //     b: "obj.b"
        // };
        // this.obj = obj

        // 第二种解决方法
        // this.$set(this.obj,"b","obj.b")
    }
}

默认情况下点击button会发现, obj.b 已经成功添加,但是视图并未刷新

原因在于在Vue实例创建时, obj.b 并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局api—— $set()

$set() 方法相当于手动的去把 obj.b 处理成一个响应式的属性,此时视图也会跟着改变了

开发过程中我用的是第一种方法解决的,但是不好的地方就是比较麻烦,很多场景实现起来非常不友好。

用vue官方提供的$set就好了Vue.set( target, propertyName/index, value )

参考:
1.Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?
2.Vue--给data数据中对象新增属性/响应式数据(使用Vue.$set()),并触发视图更新

2022年02月17日
Icefox Theme . 鄂ICP备16001608号-1