01-vue拦截原理

在原生的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
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论