在原生的js语法中,需要使用Object.defineProperty来对一个对象的属性进行get和set拦截,在对象的属性被访问时触发get方法,在对象的属性值被修改时触发set方法。
我们在页面中定义一个空对象obj,使用Object.defineProperty对obj的“myname”属性进行get/set拦截。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>01-vue拦截原理</title>
</head>
<body>
<div id="box">
</div>
<script type="text/javascript">
var obox = document.getElementById("box")
// vue底层原理,vue底层原理,vue的数据更新原理
// 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
var obj = {}
Object.defineProperty(obj, "myname", {
get() {
console.log("被访问了")
return obox.innerHTML
},
set(value) {
console.log("修改", value)
obox.innerHTML = value
}
})
</script>
</body>
</html>

当 obj的myname值被访问时,我们获取id为box的div的内容,
当obj的myname值被修改时我们给id为box的div插入obj的myname值,
这就实现了数据的双向绑定,也就是Vue的数据更新原理。
在vue中,同过el绑定dom,对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。
每个组件实例对应一个watcher实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。当依赖项的setter触发时,会通知watcher,从而使它关联的组件重新渲染。
Object.defineProperty 的缺点:
1.无法监听es6的Set、Map变化;
2.无法监听Class类型的数据;
3.无法监听属性的新加或者删除
4.无法监听数组元素的增加和删除。
Vue3中使用ES6的Proxy,能解决vue2中 Object.defineProperty 的缺点。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
请登录后发表评论
注册