欢迎光临
个人技术文档整理

Vue:数据响应式原理

数据响应式原理

Vue 的数据响应式原理是基于 JavaScript 的 Object.defineProperty() 方法实现的。该方法可以将一个对象的属性转化为 getter setter,从而在访问或修改该属性时触发相应的回调函数。在 Vue 中,每个组件都有一个对应的“响应式系统”,用于监听组件的数据变化并更新相关的视图。

当我们在 Vue 中声明一个数据对象时,Vue 会遍历该对象的每个属性,并使用 Object.defineProperty() 方法将其转化为 getter 和 setter。这样,当我们访问或修改该属性时,就会触发相应的回调函数,并通知 Vue 去更新相关的组件

 

修改数组时的一个问题和解决方法

this.personList[0] = { id: 1, name: 'aaaaaaaaaa', age: 18 } 更改data数据,Vue不监听,模板不改变


    <div id="app"> 
        <h2>学校:{{schoolName}}</h2>
        <ul>
            <li v-for="(p, index) of personList" :key="index">
                {{ p.name }}-{{ p.age }}
            </li>
        </ul>
        <button @click="updatePerson">修改第一行姓名</button> 
    </div>
    <script>
        let vm = new Vue({
            el: '#app',
            data: {
                schoolName: '北京大学',
                personList: [
                    { id: 1, name: '张三', age: 18 },
                    { id: 2, name: '李四', age: 19 }
                ]
            },
            methods: {
                //编辑数组  https://v2.cn.vuejs.org/v2/guide/list.html#变更方法
                updatePerson() {

                    //***********可行的方式***********
                    // this.personList[0].name = 'aaa';//修改属性,可以触发视图更新  vm有get,set
                    // Vue.set(this.personList, 0, { id: 1, name: 'aaaaaaaaaa', age: 18 })
                    // this.$set(this.personList, 0, { id: 1, name: 'aaaaaaaaaa', age: 18 })
                    this.personList.splice(0, 1, { id: 1, name: 'aaaaaaaaaa', age: 18 })//通过删除或替换现有元素和/或添加新元素来更改数组的内容。

                    //***********不可行的方式***********
                    // this.personList[0] = { id: 1, name: 'aaaaaaaaaa', age: 18 };//修改对象,没有触发视图更新

                }
            },
        })
    </script>

 

总结

  • vue会监视data中所有层次的数据
  • 通过setter实现监视,且要在new Vue()时就传入要监测的数据(data)
    • 对象创建后追加的属性,Vue默认不做响应式处理
    • 如需后面添加的属性做响应式,请使用如下API:
      Vue.set(target, propertyName/index, value)
      vm.$set(target, propertyName/index, value)
  • 数组监测更新方式: 通过包裹数组更新元素的方法实现: 
    • (1)调用原生对应的方法对数组进行更新
    • (2)重新解析模板,进而更新页面
  • 数组变更方法 
    push() 、pop() 、unshift() 、shift() 、splice() 、sort()、 reverse()
    Vue.set()或vm.$set()

     特别注意:Vue.set() 和 vm.$set() 不能给vm或vm的根数据对象(data等)添加属性

 

赞(1)