一、定义
vue是通过Object.defineProperty()来实现双向数据绑定的,它作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineProperty(obj, prop, desc)
- obj 需要定义属性的当前对象
- prop 当前需要定义的属性名
- desc 属性描述符
二、描述符属性配置
一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性。
Object.defineProperty(obj:对象, prop:key, descriptor:属性和方法)
let obj = {}
Object.defineProperty(obj,'a',{
configurable: true //是否允许删除
enumerable:true //是否允许枚举
value:undefined //就是value值
writable:true //是否允许赋值
get() {} //获取的return的值
set(newVal) {} //修改的时候执行 newVal就是最新的值
})
//区别在于单个截止和多个劫持
Object.defineProperties(obj,{
a:{
get() {
//需要return 否则会返回 undefined
return 1
}
set(newVal) {
//newVal 是给属性 a 最新赋的值
//可以执行函数、dom操作等一些方法
}
},
b:{
get() {}
set() {}
}
})
三、数据读写
读数据,会触发 get,并且 get 内部需要返回数据,才能读取到数据
但是由于 Object.defineProperty 的缺陷,直接在 return 后面 返回 data.name,会进入死循环,所以需要通过一个全局变量进行管理
const data = {
name: '张三',
age: 14
}
let value = data.name
Object.defineProperty(data, 'name', {
get() {
console.log('读数据了')
return value
},
set(val) {
console.log('写数据了')
}
})
console.log(data.name)
四、写数据
const data = {
name: '张三',
age: 14
}
let value = data.name
Object.defineProperty(data, 'name', {
get() {
console.log('读数据了')
return value
},
set(val) {
console.log('写数据了' + val)
value = val
}
})
console.log(data.name)
data.name = '赵四'
console.log(data.name)
// 打印结果
读数据了
张三
写数据了赵四
读数据了
赵四
五、单层数据响应
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Document</title>
</head>
<body>
<div>
<p id="name"></p>
<p id="age"></p>
</div>
<script>
// 定义数据
const data = {
name: '张三',
age: 19
}
// 同步视图的方法
function setView() {
document.getElementById('name').innerHTML = data.name
document.getElementById('age').innerHTML = data.age
}
setView()
// 利用循环对数据进行监听
Object.keys(data).forEach(key => {
// 利用外部数据进行数据的读写控制
let getValue = data[key]
Object.defineProperty(data, key, {
// 读数据
get() {
return getValue
},
// 写数据
set(val) {
getValue = val
setView()
}
})
})
</script>
</body>
</html>
六、数据无法响应的情况
https://cn.vuejs.org/v2/guide/reactivity.html