代码拉取完成,页面将自动刷新
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>vue2和vue3的响应式原理</title>
</head>
<body>
一、vue2.x的响应式:
-- 对象类型:通过Object.defineProperty()对属性的读取(getter)、修改(setter)进行拦截(数据劫持)。
-- 数组类型:通过重写更新数组的一系列(push、pop、shift、unshift、splice、sort、reverse)方法来实现拦截。(对数组的变更方法进行了包裹)。
-- Object.defineProperty只可以getter(读取)和setter(修改)方法只可以监听对象的读取和修改
1.存在问题:(由于 JavaScript 的限制,vue不能完全检测数组和对象的全部变化)
-- 新增属性、删除属性, 界面不会更新。解决:this.$set、this.$delete
-- 直接通过下标修改数组、修改数组的长度时, 界面不会自动更新。解决:this.$set、重写更新数组的一系列方法
2、总结:
Vue的双向数据绑定是由数据劫持结合发布者-订阅者模式实现的。
数据劫持:是通过 Object.defineProperty() 来劫持对象数据的setter和getter操作;
发布者-订阅者模式: 在数据变动时,发布者发布消息给订阅者,触发相应监听回调。
当一个普通的JavaScript对象传给Vue实例,来作为他的data选项时,Vue会遍历他的每个属性,使用Object.defineProperty重新定义所有属性,监听他们的getter和setter 方法,当页面取到对应属性时,会进行依赖收集(收集当前组件的watcher),如果属性发生变化会通知相关依赖进行更新操作。
(1).存在问题:(由于 JavaScript 的限制,vue不能完全检测数组和对象的全部变化)
-- 新增属性、删除属性, 界面不会更新。解决:this.$set、this.$delete
-- 直接通过下标修改数组、通过下标添加数组、delete方法删除数组、修改数组的长度时, 界面不会自动更新。解决:this.$set、重写更新数组的一系列方法:push/pop/shift/unshift/splice/sort/reverse
二、Vue3.0的响应式
- 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射): 对源对象的属性进行操作。
- MDN文档中描述的Proxy与Reflect:
- Proxy:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
- Reflect:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置(修改)属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
</body>
<script type="text/javascript">
</script>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。