vue3-06vue2(Object.defineProperty)与vue3(基于ES6的Proxy)的响应式原理对比
1.vue2响应原理
1.1对于对象与数组
对象类型: 通过 object.defineProperty() 对属性的读取、修改进行拦截 (数据劫持)
数组类型:通过重写更新数组的一系列方法来实现拦截。 (对数组的变更方法进行了包裹)
Vue2的响应式是基于Object.defineProperty实现的
1.2 基本原理Object.defineProperty
把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
// 响应式函数
function reactive(obj, key, value) {
Object.defineProperty(data, key, {
get() {
console.log(`访问了${key}属性`)
return value
},
set(val) {
console.log(`将${key}由->${value}->设置成->${val}`)
if (value !== val) {
value = val
}
}
})
}
const data = {
name: '林三心',
age: 22
}
Object.keys(data).forEach(key => reactive(data, key, data[key]))
console.log(data.name)
// 访问了name属性
// 林三心
data.name = 'sunshine_lin' // 将name由->林三心->设置成->sunshine_lin
console.log(data.name)
// 访问了name属性
// sunshine_lin
// 接着上面代码
data.hobby = '打篮球'
console.log(data.hobby) // 打篮球
data.hobby = '打游戏'
console.log(data.hobby) // 打游戏
data新增了hobby
属性,进行访问和设值,但是都不会触发get和set
,所以弊端就是:Object.defineProperty
只对初始对象里的属性有监听作用,而对新增的属性无效。这也是为什么Vue2中对象新增属性的修改需要使用Vue.$set
来设值的原因。
1.3 存在问题
新增,删除属性,页面未更新。
直接通过下标修改数组,页面未自动更新。
确保数据响应式如下
vue2-this.$set($delete,$get)确保数据响应性的实例方法-CSDN博客文章浏览阅读484次,点赞21次,收藏17次。this.$set确保数据响应性的实例方法https://blog.csdn.net/2301_76671906/article/details/145710361?fromshare=blogdetail&sharetype=blogdetail&sharerId=145710361&sharerefer=PC&sharesource=2301_76671906&sharefrom=from_link
2.vue3响应原理
Vue3的响应式是基于ES6的Proxy来实现的
对应学习来自于此处,学习记录
https://segmentfault.com/a/1190000041207010https://segmentfault.com/a/1190000041207010
vue3-07模拟vue3的响应式原理Proxy (代理对象)与Reflect (反射对象)-CSDN博客模拟vue3的响应式原理Proxy (代理对象)与Reflect (反射对象)https://blog.csdn.net/2301_76671906/article/details/145890823?fromshare=blogdetail&sharetype=blogdetail&sharerId=145890823&sharerefer=PC&sharesource=2301_76671906&sharefrom=from_link