同学刷抖音的间隙,我学会了Vue数据代理与数据劫持的原理

// 该data对象被加入到一个 Vue 实例中

var vm = new Vue({

data: data

})

上面的代码一般写成下面的形式:也就是直接在Vue函数中,传入 data 配置对象

const vm = new MVVM({

el: “#root”,

data: {

a: 1

}

})

数据代理的实质是:

1. 利用 Object.defineProperty() 方法,给new出来的Vue实例 vm ,添加和 data 配置项中一模一样的属性和值。

2. 为每一个添加到 vm 上的属性,都指定一个 getter/setter

3. 在 getter/setter 内部去操作(读/写)data 中对应的属性

我们可以在控制台打印 vm ,如下图

可以看到,每一个属性,都有一对 get/set 或 getter/setter方法,这是实现响应式变化的关键

数据代理用到的Vue构造函数伪代码如下:

function MVVM(options){

// 将选项对象保存到vm

this.$options = options

// 将data对象保存到 vm和 新定义的data变量中

var data = this._data = this.$options.data

// 将vm保存在me变量

var me = this

// 遍历data中所有属性名

Object.keys(data).forEach(function (key){

// 每次遍历,实现当前属性的代理

me._proxy(key)

})

// 对data进行监视

observe(data,this)

// 创建一个用来编译模板的compile对象,用来解析模板以及模板里的指令

this.$compile = new Compile(options.el || document.body, this)

}

MVVM.prototype = {

$watch:function(key,cb,options){

new Watcher(this,key,cb)

},

// 调用_proxy方法,对指定的属性实现代理

// _proxy方法接收一个参数key,即原data对象中每个可枚举的属性的属性名

_proxy:function(key){

// 将vm保存在me变量

var me = this

// 给vm添加指定属性名的属性

Object.defineProperty(me,key,{

configurable:false, //不能再重新定义该属性

enumerable:true, //可以枚举

// 使用vm.name的形式读取属性值时,自动调用get/getter回调函数

get:function proxyGetter(){

return me._data[key]

},

// 使用vm.name = 'XXX’形式,写操作时,自动调用set/setter回调函数

set:function proxySetter(newValue){

me._data[key] = newValue

}

})

}

}

在 new 一个 Vue 实例的时候,会调用上面的构造函数 MVVM :

构造函数 MVVM 会接收到一个选项对象 options (也叫配置对象),也就是我们上面说的 new Vue 里面的选项对象

{

el: “#root”,

data: {

a: 1

}

}

接收到 options 之后,保存在 this.$options 中。然后将data对象中的属性赋值给 this._data ,为了实现响应式, vm 会对自身 data (注意,这是 vm 自己的 data )进行修改,也就是通过**Object.defineProperty()**给每一个属性添加上 getter 和 setter 方法。

表面上,我们是在操作 vm.xxx ,实际上,我们操作的是 vm._data.xxx ,也就是 Vue 选项对象中的 data ,这就是数据代理的本质。

vm的_data中,不只是简单的选项对象中的data

尚硅谷的 Vue 全家桶课程讲解的很棒,我这里粘贴了他们的数据代理图示:

3、好处

使用数据代理,之后我们使用 vm ,访问 Vue 函数中 data 的属性时,直接 this.a 就可以了,不需要使用 this.data.a 。注意,这里的 this,指向的是 vm

三、数据劫持


1. 定义

Vue 面试题

1.Vue 双向绑定原理
2.描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?
3.你是如何理解 Vue 的响应式系统的?
4.虚拟 DOM 实现原理
5.既然 Vue 通过数据劫持可以精准探测数据变化,为什么还需要虚拟 DOM 进行 diff 检测差异?
6.Vue 中 key 值的作用?
7.Vue 的生命周期
8.Vue 组件间通信有哪些方式?
9.watch、methods 和 computed 的区别?
10.vue 中怎么重置 data?
11.组件中写 name 选项有什么作用?
12.vue-router 有哪些钩子函数?
13.route 和 router 的区别是什么?
14.说一下 Vue 和 React 的认识,做一个简单的对比
15.Vue 的 nextTick 的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?

组件中写 name 选项有什么作用?
12.vue-router 有哪些钩子函数?
13.route 和 router 的区别是什么?
14.说一下 Vue 和 React 的认识,做一个简单的对比
15.Vue 的 nextTick 的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?
[外链图片转存中…(img-kcmrn9oW-1719246226265)]

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值