「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」。
vue2的实现(4)之对象劫持的一些细节处理
回顾
- 上次内容我们介绍了
observe模块,rewrite-vue/src/observe/index.js逻辑代码主要存放在这个文件中。主要做的是对数据data的观测劫持,下面是这个文件中的代码。 rewrite-vue/src/observe/index.jsclass Observe { consturctor(data){ this.walk(data) } walk(data){ Object.keys(data).forEach(key => defineReactive(data, key, data[key])) } } export function defineReactive(target, key, value){ Object.defineProperty(target, key, { get(){ console.log('劫持用户的取值操作,get'); return value }, set(newValue){ if(newValue !== value){ console.log('劫持用户的设置操作,set'); value = newValue } } }) } export function observe(data){ if(typeof data !== 'object' || data === null){ return } return new Observe(data) }
给对象的属性赋值为一个新对象能否劫持到?
-
我们用下面的代码测试一下,在浏览器打开
rewrite-vue/dist/index.html。 -
rewrite-vue/dist/index.html<!DOCTYPE html> <html> <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>Vue2</title> </head> <body> <script src="./vue.js"></script> <script> const vm = new Vue({ data:{ name:'vue2', age:3 } }) vm._data.age = { num:666, key:'age' } console.log(vm._data.age.key); console.log(vm._data.name); </script> </body> </html> -
下面的图片是输出结果,我们可以看到第一次打印的是我们设置
vm._data.age时输出的set。我们可以看到在访问vm._data.age.key时,只打印了一次get的输出,最后一次输出的是访问vm._data.name时,打印的get。 -
按理说,我们访问了
vm._data.age.key,在访问age时打印一次get,在访问key的时候也打印一次get,这样才对。 -
所以说,我们还需要对用户设置值时的值,进行劫持。我们来改造一下,我们只需要在
set方法中,重新observe一下newValue即可。 -
rewrite-vue/src/observe/index.jsclass Observe { consturctor(data){ this.walk(data) } walk(data){ Object.keys(data).forEach(key => defineReactive(data, key, data[key])) } } export function defineReactive(target, key, value){ Object.defineProperty(target, key, { get(){ console.log('劫持用户的取值操作,get'); return value }, set(newValue){ if(newValue !== value){ console.log('劫持用户的设置操作,set'); observe(newValue) value = newValue } } }) } export function observe(data){ if(typeof data !== 'object' || data === null){ return } return new Observe(data) } -
这样
observe方法就会对我们设置的值,进行劫持。
测试
-
rewrite-vue/dist/index.html里面的代码还是上面的测试用例,我们再次在浏览器中打开rewrite-vue/dist/index.html可以看到。 -
从下面的图可以看出我们的打印已经生效了,证明我们已经拦截到了用户设置值时的操作。在访问
vm._data.age.key时打印了两次get。今天是更文第十一天加油~ 看到这里兄弟帮忙点个赞吧