<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function render() {
console.log('检测的数据', data)
console.log('模拟视图渲染')
}
let data = {
name: '浪里行舟',
location: { x: 100, y: 100 }
}
observe(data)
/**
* 对数据进行监听
* */
function observe(obj) { // 我们来用它使对象变成可观察的
// 判断类型
if (!obj || typeof obj !== 'object') {
return
}
Object.keys(obj).forEach(key => {
defineReactive(obj, key, obj[key])
})
/*
*设置成响应式
**/
function defineReactive(obj, key, value) {
/**
* 递归子属性
*/
observe(value)
//
Object.defineProperty(obj, key, {
enumerable: true, //可枚举(可以遍历)
configurable: true, //可配置(比如可以删除)
get: function reactiveGetter() {
console.log('监听get', value) // 监听
return value
},
set: function reactiveSetter(newVal) {
observe(newVal) //如果赋值是一个对象,也要递归子属性
if (newVal !== value) {
console.log('set监听', newVal) // 监听
render()
value = newVal
}
}
})
//
}
}
data.location = {
x: 1000,
y: 1000
} //set {x: 1000,y: 1000} 模拟视图渲染
data.name // get 浪里行舟
</script>
</body>
</html>