来源
尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通
数据代理
通过vm对象来代理data对象中属性的操作(读/写)
通过Object.defineProperty()
把data对象中所有属性添加到vm上。
为每一个添加vm上的属性都指定一个getter/setter
在getter/setter内部去操作(读/写)data中对应的属性
认识Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
let person = { | |
name:'张三', | |
sex:'男', | |
//age:18 | |
} | |
//不可枚举(不被遍历) | |
Object.defineProperty('person','age',{ | |
value:18 | |
}) | |
console.log(Object.keys(person)); | |
//配置可以枚举 | |
Object.defineProperty('person','age',{ | |
value:18, | |
enumerable:true,//控制属性是否可以被枚举,默认false | |
writable:true,//控制属性是否可以被修改,默认false(默认不可以修改age的值) | |
configurable:true,//控制属性是否可以被删除,默认false(默认不可以删除age的值`delete person.age`) | |
}) | |
console.log(Object.keys(person)); |
高级用法
let number = 18 | |
let person = { | |
name:'张三', | |
sex:'男' | |
} | |
Object.defineProperty('person','age',{ | |
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值 | |
get(){ | |
console.log("有人读取了age属性") | |
return number | |
}, | |
//当有人修改person的age属性时,set函数(setter)就会被调用,且收到修改的具体值 | |
set(value){ | |
console.log("有人修改了age属性,且值是",value) | |
number = value | |
}, | |
}) |
实例详解
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>数据绑定</title> | |
</head> | |
<body> | |
<div id="app"> | |
<div>{{name}}</div> | |
</div> | |
<script src="./vue.js"></script> | |
<script> | |
Vue.config.productionTip = false //阻止vue在启动时生成生产提示 | |
const vm = new Vue({ | |
el: "#app", | |
data: { | |
name: "数据绑定", | |
}, | |
}) | |
</script> | |
</body> | |
</html> |
console.log(vm)
通过Object.defineProperty()
把data对象中所有属性添加到vm上。
为每一个添加vm上的属性都指定一个getter/setter
vm._data === options.data
# true
{ | |
el: "#app", | |
data: { | |
name: "数据绑定", | |
}, | |
} |
vm.name = "修改数据绑定了"
在getter/setter内部去操作(读/写)data中对应的属性
执行过程 vm.name => setter => data
vm._data.name = "恢复数据绑定了"
{{name}} 等于 {{_data.name}}
- {{name}}等于读取(getter)_data.name
- _data不是数据代理而是数据劫持