b站面试题讲解:
vue面试题讲解4
observer.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>何如让数据变得可观测</title>
</head>
<body>
<h1>每一个属性都可以被观测</h1>
<script type="module">
import { Observer } from './observer.js'
let obj = new Observer({
name: 'chenqingxian',
age: 25,
demo: {
a: 'aaa',
b: 12
}
})
// console.log(obj.value.age) //时间:19.17; 1.没有打印观察;2.value从哪里来的?
// obj.value.age = 26
console.log(obj.value.demo.a)
obj.value.demo.b = 1236
</script>
</body>
</html>
observer.js
// 四--变化监听
// data
export class Observer {
constructor(data) {
// this.walk(data);
this.value = data;
console.log('--Observer--constructor--data:');
if (Array.isArray(data)) {
console.log('--Array.isArray数组');
}
if (data instanceof Array) {
// 数组逻辑
console.log('--data instanceof Array');
} else {
// 对象逻辑
console.log('--data instanceof class');
this.walk(data);
}
}
walk(obj) {
// // 遍历
// Object.keys(obj).forEach((key) => {
// this.defineReactive(obj, key);
// });
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
defineReactive(obj, key);//
}
}
}
//循环 让每个对象都变成可观测
// 此处val一定是空,只有前两个参数;可以在下面的函数中少定义一个参数
function defineReactive(obj, key, val) {
// function defineReactive(obj, key) {
// let val = null;
console.log(`$defineReactive:${key}属性被监听了,obj:${JSON.stringify(obj)},val:${val}`);
if (arguments.length === 2) {
val = obj[key];
}
if (typeof val === 'object') {
// 递归
new Observer(val);
}
Object.defineProperty(obj, key, {
enumerable: true, // 枚举
configurable: true, // 可配置。可变化
get() {
console.log(`$get:${key}属性被读取了`);
return val;
},
set(newVal) {
console.log(`$set:${key}属性被修改了,newval:${newVal},oldval:${val}`);
val = newVal;
}
});
}
错误:
1. walk函数中:
this.defineReactive(obj, key);
需要去掉this
2. 参数
obj
:一个响应式对象,用于添加新的响应式属性。key
:要添加的响应式属性的键名。
3. 递归:
if (typeof val === 'object') {
// 递归
new Observer(val);
}