1. 原理
1.1 defineReactive简单版
利用Object.defineProperty() 实现数据的响应,注意需要用一个temp把 值存起来
let temp;
let obj = {a:1}
defineReactive(obj,"a")
function defineReactive(obj,key) {
Object.defineProperty(obj,key,{
get () {
console.log("调用get方法,temp",temp)
// console.log("obj[key]",obj[key]) //为什么不直接用 obj[key] 因为又会死循环重复调用get
return temp
},
set (val) {
console.log("调用set方法,val",val)
temp = val
return
}
})
}
obj.a
obj.a = 2
obj.a
//调用get方法,temp undefined
//调用set方法,val 2
//调用get方法,temp 2
复制代码
1.2 defineReactive闭包版
方法参数再方法体内被返回,形成闭包
let obj = {}
defineReactive(obj,"a",'1')
function defineReactive(obj,key,val) {
Object.defineProperty(obj,key,{
get () {
console.log("调用get方法,val",val)
return val //直接返回 参数val 形成闭包
},
set (newVal) {
console.log("调用set方法,newVal",newVal)
if(val === newVal) {
return
}
val = newVal
return
}
})
}
obj.a
obj.a = 2
obj.a
// 调用get方法,val 1
// 调用set方法,newVal 2
// 调用get方法,val 2
复制代码
1.3. 简单的页面响应
简单html定时自动数据响应刷新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<script>
let obj = {}
defineReactive(obj,"a",'1')
function defineReactive(obj,key,val) {
Object.defineProperty(obj,key,{
get () {
console.log("调用get方法,val",val)
return val //直接返回 参数val 形成闭包
},
set (newVal) {
if(val === newVal) {
return
}
console.log("调用set方法,newVal",newVal)
val = newVal
updateFn()
}
})
}
let app = document.getElementById("app")
function updateFn() {
app.innerHTML = obj.a
}
setInterval(() => {
obj.a = new Date().toLocaleTimeString();
}, 1000);
</script>
</body>
</html>
复制代码
1.4. 遍历所有属性
//观察方法
function observe(obj) {
if (typeof obj !== "object" || obj == null) {
return
}
Object.keys(obj).forEach( k => {
defineReactive(obj,key,obj[key])
})
}
复制代码
1.5. 遍历所有属性
//观察方法
function observe(obj) {
if (typeof obj !== "object" || obj == null) {
return
}
Object.keys(obj).forEach( key => {
defineReactive(obj,key,obj[key])
})
}
复制代码
1.6. 解决嵌套对象问题
function defineReactive(obj, key, val) {
observe(val) //判断值是不是也是对象 递归调用
}
复制代码
1.7. 插入值是对象处理
set(newVal) {
if (newVal !== val) {
observe(newVal) // 赋值的时候也调用一下
...
}
}
// vue的set方法就是这个原理
function set(obj, key, val) {
defineReactive(obj, key, val)
}
复制代码
2. 实战
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)