1let activeEffect = undefined;
2const targetMap = new WeakMap();
3
4const effect = function (fn) {
5 activeEffect = fn;
6 fn();
7}
8
9const track = function (target, key) {
10 const dep = targetMap.get(target) || new Map();
11 const funcs = dep.get(key) || new Set();
12 funcs.add(activeEffect);
13 dep.set(key, funcs);
14 targetMap.set(target, dep);
15}
16
17const trigger = function (target, key) {
18 const dep = targetMap.get(target);
19 if (dep && dep.get(key)) {
20 dep.get(key).forEach(fn => fn());
21 }
22}
23
24const reactive = function (target) {
25 return new Proxy(target, {
26 get(target, key, reciever) {
27 track(target, key);
28 return Reflect.get(target, key, reciever);
29 },
30 set(target, key, value, reciever) {
31 Reflect.set(target, key, value, reciever);
32 trigger(target, key);
33 }
34 });
35}
36
37const person = {
38 firstName: 'Lu',
39 lastName: 'xun',
40 get name() {
41 return this.firstName + this.lastName;
42 }
43}
44
45const proxy = reactive(person);
46
47effect(() => {
48 console.log('effect1', proxy.name)
49});
50effect(() => {
51 console.log('effect2', proxy.name)
52});
53
54proxy.firstName = 'Zhang';1// 实现一个observer方法——要监听的对象属性可配置
2// https://juejin.cn/post/7114588899661316126
3function observer(obj, path, cb) {
4 path.forEach((key) => {
5 let value = "";
6 if (key) {
7 const _key = key.split(".");
8 if (_key.length > 1) {
9 let tmp = obj;
10 // 循环,为了取到属性值,不断地赋值给 tmp
11 _key.forEach((k) => {
12 // 递归,对每一个层级都进行劫持,要不然无法监听到深层级的属性值变化
13 observer(tmp, [k], cb);
14 tmp = tmp[k];
15 });
16 value = tmp;
17 } else {
18 value = obj[key];
19 }
20
21 Object.defineProperty(obj, key, {
22 get() {
23 return value;
24 },
25 set(newV) {
26 if (newV !== value) {
27 cb && cb(newV, value);
28 value = newV;
29 }
30 },
31 });
32 }
33 });
34}
35
36var o = {
37 a: 1,
38 b: 2,
39 c: {
40 x: 1,
41 y: 2,
42 },
43};
44
45observer(o, ['a', "c.x"], (v, prev) => {
46 console.log("newV=", v, " oldV=", prev);
47});
48
49o.a = 2; // 2, 1
50o.b = 3; // 不打印
51o.c.x = 3; // 3, 1
52o.c.y = 3; // 没有没监听,不打印1//简单实现vue的更新方法,递归实现
2function update(obj, key, value) {
3 if (typeof obj !== 'object' || obj === null) {
4 return;
5 }
6 // 递归遍历对象属性
7 for (let prop in obj) {
8 if (obj.hasOwnProperty(prop)) {
9 if (typeof obj[prop] === 'object') {
10 update(obj[prop], key, value); // 递归调用更新方法
11 } else if (prop === key) {
12 obj[prop] = value; // 更新属性值
13 }
14 }
15 }
16}
17
18// 示例用法
19const data = {
20 name: 'John',
21 age: 30,
22 address: {
23 city: 'New York',
24 state: 'NY',
25 country: 'USA'
26 }
27};
28
29console.log('Before update:', data);
30update(data, 'city', 'San Francisco');
31console.log('After update:', data);1let template = "我是{{name}},年龄{{age}},性别{{sex}},子姓名:{{nest.subName}}";
2let data = {
3 name: "姓名1",
4 age: 18,
5 nest: {
6 subName: '姓名1-1'
7 }
8};
9
10function render(template, data) {
11 return template.replace(/\{\{(.+?)\}\}/g, function (match, key) {
12 const keys = key.split('.'); // Split the key by dot to handle nested properties
13 let value = data;
14
15 // Traverse the nested properties
16 for (const k of keys) {
17 value = value[k];
18 if (value === undefined) {
19 break; // Stop if any intermediate property is undefined
20 }
21 }
22
23 return value !== undefined ? value : '';
24 });
25}
26
27console.log(render(template, data));
28// Output: 我是姓名1,年龄18,性别,子姓名:姓名1-11function isObject(val) {
2 return val !== null && !Array.isArray(val) && typeof val === "object";
3}
4
5function observe(obj) {
6 if (!isObject(obj)) {
7 return;
8 }
9 Object.keys(obj).forEach((key) => {
10 var dep = new Dep();
11 // 重新定义属性
12 var internalValue = obj[key]; // 缓存该属性的值
13 observe(internalValue); // 递归监听该属性
14 Object.defineProperty(obj, key, {
15 get() {
16 dep.depend(); // 看一下,是哪个函数用到了我这个属性,将该函数记录下来
17 return internalValue;
18 },
19 set(val) {
20 observe(val);
21 internalValue = val;
22 dep.notify(); // 通知所有用到我这个属性的函数,全部重新运行
23 },
24 });
25 });
26}
27
28function Dep() {
29 this.subscribes = new Set(); // 用于记录依赖
30}
31
32Dep.prototype.depend = function () {
33 if (activeUpdate) {
34 this.subscribes.add(activeUpdate);
35 }
36};
37
38Dep.prototype.notify = function () {
39 this.subscribes.forEach((fn) => fn());
40};
41
42var activeUpdate = null; // 当前正在收集依赖的函数
43
44function autorun(fn) {
45 function updateWrapper() {// 防止后面的依赖收集不到,所以谈一层函数
46 activeUpdate = updateWrapper;
47 fn(); // 该函数的运行期间,activeUpdate一定有值
48 activeUpdate = null;
49 }
50 updateWrapper();
51}
52
53var state = {
54 name: "monica",
55 age: 18,
56 addr: {
57 province: "黑龙江",
58 city: "哈尔滨",
59 },
60};
61
62observe(state);
63
64autorun(() => {
65 state.age;
66 state.name
67 console.log('autorun')
68});
69
70state.age = 19;
71state.name = "Kevin Woo";
72// state.addr.province = "四川";
73// state.addr.city = "成都";
74
75// 设置没有的属性,删除属性监控不到,所以要用$set,$delete