Vue的绑定原理

479 阅读2分钟

1.Vue的绑定原理:其实就是 new Vue的原理

(1).先创建一个vue类型的子对象

a.引入data对象:

1). 自动为data对象中每个变量都请了保镖(访问器属性)!
		结果: 任何位置访问data中的变量时,其实根本就不是直接访问data中变量,仅仅访问的是为data中的变量请的同名保镖而已
		结果: 只要外界试图修改data中的变量时,注定会触发保镖的set()方法。
2). new Vue()还自动在每个变量的set()函数内植入了一个通知函数
		结果: 只要外界试图修改data中的变量时,注定会触发保镖的set()方法中的通知函数。整个vue框架就知道一个变量的值被修改了!

b.引入并打散methods对象:

1). Methods中所有函数默认直接隶属于new Vue()对象
		2). 导致methods中的函数进入new Vue()后和data中变量的保镖(访问器属性)平级
		3). 所以,methods中的方法想访问data中的变量,必须加this.变量名

(2).构建虚拟DOM树:

a.什么是虚拟DOM树

通过扫描完整版DOM树创建出的一棵新DOM树

b.过程

1). new Vue()会查找到el属性指定的界面上的父元素
2). 扫描找到的父元素及其子元素
3). 碰到"@事件名=函数名",就自动翻译为on事件名=函数名——自动绑定事件
4). 碰到所有"{{变量名}}":
	i. 先将可能变化的元素对象加入到虚拟DOM树中
	ii. 并且首次替换元素内容中{{变量名}}为变量的初始值

(3)结果

每次只要data中的变量被修改时:

a. 自动调用变量的set()函数
b. set()中内置的通知函数向vue框架发出通知,说xx变量发生了改变
c. 框架会自动扫描虚拟DOM树
d. 查找受本次变量修改影响的所有DOM元素
e. 自动利用已经提前封装好的DOM增删改查操作,只更新页面上受影响的元素。其他不受该变量影响的元素,保持不变!

(4)总结

1.VUE绑定原理

访问器属性+虚拟DOM树 
访问器属性+观察者模式+虚拟DOM 

2.虚拟DOM树的优点

(1). 内容少!仅保存可能变化的元素。不变的元素一个都不包含
  (2). 遍历快!
  (3). 避免大量重复代码!——自动执行DOM增删改查操作
  (4). 效率高!每次变量更改时,只修改个别受影响的元素,其他元素保持不变!

图片2.png

观察者模式

当一个变量值被修改时,可以自动通知所有关注这个变量的其他对象,让他们自动重新获得这个变量的新值

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
<script>
//观察者(observer)模式: 当一个变量值被修改时,可以自动通知所有关注这个变量的其他对象,让他们自动重新获得这个变量的新值。
var data={
  money:1000,
  setMoney(money){
    this.money=money;
    //只要money被修改,就要调用notifyAll()
    this.notifyAll();
  },
  observers:[],
  notifyAll(){
    this.observers.forEach(function(obj){
      obj.getMoney() //要求,凡是进入observers数组中的对象,必须自身携带一个getMoney()函数,表示自己是关注money变化的
    })
  }
}

var obj1={
  money:0,
  getMoney(){
    console.log(`obj1得知data的money被改为${data.money},并重新获得data.money`);
    this.money=data.money;
  }
}
var obj2={
  money:0,
  getMoney(){
    console.log(`obj2得知data的money被改为${data.money},并重新获得data.money`);
    this.money=data.money;
  }
}
var obj3={
  money:0,
  getMoney(){
    console.log(`obj3得知data的money被改为${data.money},并重新获得data.money`);
    this.money=data.money;
  }
}
data.observers.push(obj1);
data.observers.push(obj2);
data.observers.push(obj3);
data.setMoney(900);
console.log(obj1.money, obj2.money, obj3.money)
data.setMoney(800);
console.log(obj1.money, obj2.money, obj3.money)
</script>
</body>
</html>

observer.png