05-数据代理

1.数据代理

学习数据代理需要 js 的一些知识:1Object.defineProperty(),属性标志,属性描述符,getter,setter。。。

1.1数据代理

建议学习文章地址:

这里简单介绍一下:

属性标志:

对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”

  • writable — 如果为 true,则值可以被修改,否则它是只可读的
  • enumerable — 如果为 true,则表示是可以遍历的,可以在 for.. .inObject.keys()中遍历出来
  • configurable — 如果为 true,则此控制属性可以被删除,默认值是false
1
2
3
4
Object.defineProperty(obj, prop, descriptor)
obj:要定义属性的对象。
prop:要定义或修改的属性的名称
descriptor:要定义或修改的属性描述符

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let number = 18;
let person = {
name: '张三',
sex: '男',
};

Object.defineProperty(person, 'age', {
// value:18,
// enumerable:true, // 控制属性是否可以枚举,默认值是false
// writable:true, // 控制属性是否可以被修改,默认值是false
// configurable:true // 控制属性是否可以被删除,默认值是false

// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
console.log('有人读取age属性了');
return number
},

// 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
console.log('有人修改了age属性,且值是', value);
number = value
}
});
// console.log(Object.keys(person))
console.log(person)

1.2 vue 中的数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)

1
2
3
4
5
6
7
8
9
10
11
12
13
let vm = {};
let data = {
name: 'ds',
age: 18,
};
Object.defineProperty(vm, 'age', {
get() {
return data.age;
},
set(value) {
data.age = value;
},
});

image-20220627121636057

使用 插值语法获取 vmx 时,触发 get 方法,返回 datax

修改 data 中的 age 时并没有改变 vm 里的 age 的值,当 获取 vmage 的值时,就会将 dataage 赋值给 vmage

修改 vm 中的 age 触发 set 方法,将修改的值赋值给 data 中的 age

  1. Vue 中的数据代理通过 vm 对象来代理 data 对象中属性的操作(读/写)
  2. Vue 中数据代理的好处:更加方便的操作 data 中的数据
  3. 基本原理
    • 通过 object.defineProperty()data 对象中所有属性添加到 vm
    • 为每一个添加到 vm 上的属性,都指定一个 getter,setter
    • getter,setter 内部去操作(读/写)data中对应的属

image-20220627120432752

Vuedata 中的数据拷贝了一份到 _data 属性中,又将 _data 里面的属性提到 Vue实例 中(如name),通过 defineProperty 实现数据代理,这样通过 geter/setter 操作 name,进而操作 _data 中的 name。而 _data 又对 data 进行数据劫持,实现响应式。

name被修改–>调用setter–>重新解析模板–>生成新的虚拟DOM–>新旧DOM对比(diff)–>更新页面


05-数据代理
https://flepeng.github.io/021-frontend-04-Vue-01-course-05-数据代理/
作者
Lepeng
发布于
2023年8月10日
许可协议