Vue中关于数组与对象修改触发页面更新的机制与原理简析

科技资讯 投稿 26900 0 评论

Vue中关于数组与对象修改触发页面更新的机制与原理简析

Vue中关于数组与对象修改触发页面更新的机制与原理简析

相关问题

数组

例如:

<script>
export default {
    name: "HomeView",
    data: ( => ({
        list1: ["A", "B"],
    },
    methods: {
        btnClicked( {
            this.list1[0] = "C"
            this.list1[2] = "C"
        },
    },
}
</script>

或是

<script>
export default {
    name: "HomeView",
    data: ( => ({
        list1: [{ text: "123" }, { text: "456" }],
    },
    methods: {
        btnClicked( {
            this.list1[0] = { text: "789" }
        },
    },
}
</script>

页面并不会触发更新。

对象

例如:

<script>
export default {
    name: "HomeView",
    data: ( => ({
        obj1: { a: "a", b: "b" },
    },
    methods: {
        btnClicked( {
            this.obj1.c = "c"
        },
    },
}
</script>

页面并不会触发更新。

原因

然而对于在页面渲染完成后加入data的属性,Vue并不会将其变为响应式。

一些深入的探究

数组

下标本身是无法成为响应式的。

data: ( => ({
        list1: [{ text: "123" }, { text: "456" }],
}

使用如上的data声明。

this.list1[0] = { text: "789" }

方法B:

this.list1[0].text = "789"

方法B可以被正确响应而方法A不可以。

同时,由于数组下标为0的位置替换为了一个新的对象,而这个新的对象并没有被配置为响应式,那对于这个对象属性的修改也不会触发页面更新。如下:

this.list1[0] = { text: "789" }
this.list1[0].text = "456"

由于新的对象的属性并没有被配置为响应式,那么即使对这个对象的属性进行修改,页面也不会被更新。

下标本身无法成为响应式,不妨尝试:

<script>
export default {
    name: "HomeView",
    data: ( => ({
        list1: ["A", "B"],
    },
    methods: {
        btnClicked( {
            this.list1[0] = "C"
        },
    },
}
</script>

通过下标修改数组的对应值也无法触发视图更新。

对象

data: ( => ({
        obj1: { a: { text: "a" }, b: { text: "b" } },
},

使用如上的data声明。

this.obj1.a = { text: "c" }

成功触发视图更新。

解决方案

数组

1.  内置API

如果需要向数组加入新的成员,则可以直接使用数组的push方法。

  • push(

  • pop(

  • shift(

  • unshift(

  • splice(

  • sort(

  • reverse(

2.  将数组重新赋值,修改引用地址

为数组新增一个字符串成员"C"
this.list1 = this.list1.concat(["C"]

由于list1是data的属性,list1的引用发生改变,就会触发视图更新

修改数组的第一个值
let tempList = this.list1.concat([] // 深拷贝,等价于一个新数组,使用slice,JSON都可以。
tempList[0] = "666"
this.list1 = tempList

通过原数组新建一个新数组,修改新数组后再将新数组赋值给原数组,由于原数组作为data的属性,其引用被修改触发视图更新

3.  Vue.$set( 方法

触发视图更新。

Vue.$set(对象或数组, 对象属性名或数组下标, 值

向list1对象的0索引位置赋值一个新的响应式对象,同时触发视图更新:

Vue.$set(this.list1, 0, { text: "789" }

如果在组件中应使用this.$set来代替:

this.$set(this.list1, 0, { text: "789" }

对象

1.  将对象重新赋值,修改引用地址

思路与数组的类同。

深拷贝完成后修改对应属性后赋值给原对象即可。

2.  Vue.$set( 方法

定义:

Vue.$set(对象或数组, 对象属性名或数组下标, 值

将obj1对象的a属性赋值为字符串"b"并触发视图更新:

Vue.$set(this.obj1, a, "b"

如果在组件内,则应使用:

this.$set(this.obj1, a, "b"

编程笔记 » Vue中关于数组与对象修改触发页面更新的机制与原理简析

赞同 (108) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽