html
<!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>
<script type="module">
import { Observer } from "./01_数据驱动原理.js"
let obj = new Observer({
name: "cc",
age: 18,
address: {
name: "北京"
}
})
console.log(obj.value.name);
obj.value.name = "zs"
console.log(obj.value.name);
console.log(obj.value.address.name);
obj.value.address.name = "上海"
console.log(obj.value.address.name);
</script>
</body>
</html>
JS实现
Vue的核心是
1.组件化
2.数据驱动,减少dom操作优化性能
javascript
/ 怎么使得数据可观测?
// data()数据中心会有很多值
// 要通过一个类去劫持对象中的所有属性
export class Observer {
constructor(value) {
// 初始化
this.value = value
/**
* value可能是数组也可能是对象,当然也会是基本数据类型
*/
if (Array.isArray(value)) {
// 判断是不是数组
} else {
// 对象逻辑
this.walk(value)
}
}
// 操作,让每一个值都变成可观测的
walk(obj) {
// 拿到对象里的key值
// {name:"cc".age:18}
// key是name age
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
// 让key一个一个变成可观测的
defineReactive(obj, keys[i])
}
}
}
// 让一个对象所有的属性都变成可观测的
// 参数1:具体的对象,参数2:key值,参数3:value
function defineReactive(obj, key, value) {
// value必然是不存在的,
// 这只是一个简单的省略let的写法
if (arguments.length === 2) {
// value的作用很简单
// 如果value定义在形参里
// 就不用再去let一个value
// let value = obj[key]
value = obj[key]
}
if (typeof value === 'object') {
// 如果value是对象
// 那么对象里还有对象
// 那么就要递归
console.log('value是对象');
// 不递归只会进来一次
// 递归
new Observer(value)
}
Object.defineProperty(obj, key, {
// 改变这个对象
enumerable: true, // 可枚举
configurable: true, // 对象可改变
get() {
console.log(`某一个属性${key}被读取了`);
return value
},
set(newValue) {
console.log(`${key}属性被修改了,新值为${newValue}`);
value = newValue
}
})
}