使用访问器属性,模拟Vue的绑定原理

有这样一段HTML

<h1>Welcome</h1>
<h2>积分:{{scroe}}</h2>
<h1>用户名:{{uname}}</h1>
<h2>积分:{{score}}</h2>

分析new Vue()做了哪些事

1、改造data对象中的属性,并通过访问器属性对每个变量进行保护

var data = {
	uname:"dingding",
	score:2000
}

2、遍历真实DOM树,并创建虚拟DOM树->一个数组,记录可能会发生改变的元素
3、当元素发生改变时,通知虚拟DOM树,虚拟DOM树对比变化,将变化的值修改到真实DOM树上

模拟Vue绑定

var data = {
	uname:"dingding",
	score:2000
}

/ *
  * 改造data为访问器属性
  * /
 
//获取data里的全部属性名
var keys = Object.keys(data)
console.log(keys) //Array['uanme','score']
//遍历data中每个属性
for(var key of keys){
	//闭包保护循环变量key
	(function(key) {
	    //每遍历一个属性,就要改造这个属性为访问器属性
		Object.defineProperties(data,{
			//先定义一个以_开头,后面跟当前变量名的隐藏变量,实际保存当前属性值
			[`_`+key]:{ //_uname
				value:data[key], //data['uname']=>"dingding"
				writable:true,
				enumerable:false
			},
			//用一个和当前属性同名的访问器属性,代替data中原普通属性
			[key]:{//uname
				get(){return this[`_${key}}`]} //return this['_uname']
				set(value){
					this.[`_${key}`] = value // this['_uname']=value
					//发出通知给虚拟DOM树
					change(key)
				}
				enumerable: true
			}
		})
	})(key)
}
/ *
  * 构建虚拟DOM* /

//准备数组保存所有可能受影响的元素
var arr = []
// 创建虚拟DOM树
function getChildren(parent) {
	//获取子节点
	var children = parent.children
	//遍历节点
	for (var c of children) {
		//如果子节点下边还有子节点,继续遍历
		if (c.children.length>0) {
			arguments.callee(c)
		} else { // 如果是最后一级节点,则循环插入虚拟DOM树
			//遍历data中每个变量名
			for (var key of keys) {
				//碰到{{}}包裹的变量,就添加进虚拟DOM树
				if (c.innerHTML == `{{${key}}}`) {
					arr.push({
						elem:c, //虚拟DOM树中每个元素,不但要记录DOM元素对象地址[span,div...]
						innerHTML:c.innerHTML //还要记录这个DOM元素哪个属性发生变化
					})
					//首次填充页面内容
					c.innerHTML = data[key]
				}
			}
		}
	}
}
// 遍历body
getChildren(document.body)
/ *
  * 通知函数
  * /
function change(key) {
	//遍历虚拟DOM树
	for (var obj of arr) {
	// 当当前节点的内容收到当前属性key变化影响时
		if (obj.innerHTML == `{{${key}}}`) {
			//更新真实DOM元素的内容为data中当前key属性的实时值
			obj.elem.innerHTML = data[key]
		}
	}
}
Object.seal(data)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知猪狭

恰饭恰饭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值