Vue数据响应式

230 阅读3分钟

官方文档链接
响应是什么?就是当你做一件事得到回应
Vue的数据响应就是当数据改变就会自动更新视图不需要我们去操作DOM,Vue2数据响应的核心是利用了Object.defineProperty对数据进行监听代理

vue对data做了什么

下面声明了一个全局的myDtata,然后在实例中引用了这个数据,在三秒钟之后从外部改变了数据
让我们看看发生了什么

数据响应式
???。。。传入vue前的myData和传入后的myData怎么不一样 怀着疑问我们学点前置知识

getter

我们都知道对象可以写属性和方法,方法的调用方式都要加括号对吧
下面就是不加括号的骚操作

getter
总结:getter 就是这样用的 不加括号的函数,仅此而已,获得数据

setter

当我们使用下面代码的时候就会触发setter (setter用来修改数据)

boj2.姓名 = '新值'

setter

Object.defineProperty

可以给对象添加属性value
可以给对象添加getter/setter
getter/setter用于对属性的读写进行监控
当我们定义完一个对象之后,如果我们想在该对象身上额外的加上getter/setter我们需要用Object.defineProperty来做

definePropert

监听

假设我们现在有个需求,要求n不能小于负一,我们可以这么写

set设限
可以看到我们如果直接修改data2.n是不能修改的
但是杠精会说我直接修改data2._n不就可以了吗?是的,算你狠,我们继续往下看

既然你通过修改我存储数据的,那我先把n的值先存起来,用Object.defineProperty()创建一个虚拟的n覆盖掉之前的那个n,新的虚拟的n的变化会被监听的死死的,你就算修改了之前的数据n,却依旧改变不了。。。说的有点乱,来。。。。看代码

监听

监听|代理

对原来的my对象属性读写,全权交给另一个对象obj
那么obj就是代理

代理监听
vm = new Vue({data:mydata})

  1. 会让vm成为myData的代理(proxy)
  2. 会对mydata的所有属性进行监控 如果修改vm.n那么ui中的n就会响应,vue2通过Object.defineProperty实现数据响应式

Vue.set | this.$set

如果一开始没有声明某项数据,Oject.defineProperty是无法监听,vue会报错,对于值为underfined/null的情况,vue不会渲染到页面
但vue只会检查一层

追加数据监听
追加数据监听

注意事项

例子

修改是异步的
因为ui更新是异步的,它会等所有的任务队列完成后才去执行rander

详细答案

Vue数组

为了数据响应式,还修改了对数组操作的方法
我们先证明,不用数组方法,数组发生变化,不会渲染页面

Vue数组
前面说了如果数据没有提前声明就不会被监听,需要用Vue.set,但如果我们遇到了要给数组里面的数据添加监听怎么办?那得需要写多少个Vue.set呀?

别担心,Vue的数组继承了Array的所有方法,同时对其进行了修改,可以让我们做到像使用数组一样添加数据,同时被监听

大概实现思路

//注:不是源码哦
class VueArray extends Array{
    push(..args)
    const oldLength = this.length//当前数组
    super.push(...args)
    console.log('你 push 了')
    for(let i  = oldLength;i<this.length;i++){
        Vue.set(this,i,this[i])
    }
}