17vue监测数据原理

vue监测数据原理

一、更新数据时的一个错误

当我们通过方法更新单个属性时是可以被vue给监视到的,但是当我们将一个对象替代后,vue不承认的代码是被修改过。

二、监测数据的原理

vue监视数据的原理:
	1.vue会监视data中所有层次的数据。
    2。如何监测对象中的数据?
        通过setter实现监视,且要在new Vue时就传入要监测的数据。
            (1).对象中后追加的属性,Vue默认不做响应式处理
            (2).如需给后添加的属性做响应式,请使用如下API:
                Vue.set(target, propertyName/index, value)或 
                vm.$set(target, propertyName/index, value)
    3.如何监测数组中的数据?
        通过包裹数组更新元素的方法实现,本质就是做了两件事:
            (1).调用原生对应的方法对数组进行更新。
            (2).重新解析模板,进而更新页面。
    4.在Vue修改数组中的某个元素一定要用如下方法:
        1.使用这些API:push()、pop()、shift()、unshift()、splice()、 sort()、reverse()
        2.Vue.set()或vm.$set()
    特别注意:Vue.set()和vm.$set()不能给vm或 vm的根数据对象添加属性!!!

一)监测对象中数据的改变

image-20220829154731383

给数据匹配 setter,只要数据发生变化,就会知道。

  • name 改变 ---> setter 调用 ---> 重新解析模板 ---> 生成新Vnode ---> 新旧Vnode对比(diff算法) ---> 更新页面

总结: 只要数据被修改,则会调用setter 直接重新解析模板。(监视数据)

Vue.set() or vm.$set()

  • 后天添加的数据是不做响应式的(没有 getter 和 setter)
  • 使用Vue.set() 的范围是:对象不能是Vue 实例,(vm) 或者 Vue实例的根数据对象。(data, vm._data)

image-20220829171659286

image-20220829172055275

二)监测数组中数据的改变

  • 直接使用数组的索引修改,vue 不承认其修改。
  • 通过常用操作数组的方法对原数组改变, vue会承认其修改。

变更方法

Vue将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

注意: 由于执行数组是vue所管理的,所以此数组调用的方法 !== 数组的方法。
​ 此方法先调用原数组的方法,后再重新解析模板,更新数据。

替换数组

变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如:filter()concat()slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:

removeSmoke(){
    this.hobby = this.hobby.filter((h)=>{
        return h != '抽烟'
    })
}

统计数组

reduce(func,start_value)

return this.todos.reduce((prev, todo)=>{
    return prev + (todo.done ? 1 : 0)
},0)

return this.todos.reduce((prev, todo)=> prev + (todo.done ? 1 : 0), 0)

filter(func)

return this.todos.filter((todo)=>{
    return todo.done == true
}).length

return this.todos.filter(todo => todo.done == true).length

补充:

  • 数据劫持
    • 数据劫持表现上
      • 将原始的data数据改为vm._data形式,(变化,行为,操作)就被称之为数据劫持。
    • 例:
      • 修改student属性,被setter劫持。
        • setter 正常修改数据
        • 重新解析模板
  • 数据劫持 && 数据代理
    • Object.defineProperty(obj,key,options)
posted @ 2022-09-06 16:19  Redskaber  阅读(155)  评论(0)    收藏  举报