当前位置: 代码迷 >> 综合 >> 【Vue高级】MVVM实现原理(二)—— 数据劫持【Observer】,observer有观察员、观察值的意思
  详细解决方案

【Vue高级】MVVM实现原理(二)—— 数据劫持【Observer】,observer有观察员、观察值的意思

热度:40   发布时间:2023-11-29 13:18:50.0

Vue实现这种数据双向绑定的效果,需要三大模块:

  1. Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
  2. Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
  3. Watcher:作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

Observer

Observer的核心是通过Obeject.defineProperty()来监听数据的变动,这个函数内部可以定义setget,每当数据发生变化,就会触发set。这时候Observer就要通知订阅者,订阅者就是Watcher

<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head><body>{
   {a}}
</body>
<script src="./mvvm.js"></script>
<script>let vue = new Vue({el:'#app',data:{a:{a:1}}})console.log(vue)
</script>
</html>

new Vue的时候,会把vue的data属性进行递归,用Object.defineProperty()方法把这些属性全部转成set、get方法 

当data中的某个属性被访问时,则会调用get方法,当data中的属性被改变时,则会调用set方法。

function Vue(options={}){this.$options = options;//将所有属性挂载在optionsvar data = this._data = this.$options.data;//观察者  递归处理传进来的dataobserve(data)//观察完之后,this代理了this._data  数据代理for(let key in data){Object.defineProperty(this,key,{enumerable:true,get(){return this._data[key];//获取到新值},set(newVal){this._data[key] = newVal//这里触发观察者【再次执行Observe(data)中的set方法】}})}
}//观察者  vm.$options
function Observe(data){//这里写我们的主要逻辑for(let key in data){//把data属性通过object.defineProperty的方式定义let val = data[key]observe(val)//递归 使data的中的每个属性都被Object.defineProperty处理Object.defineProperty(data,key,{enumerable:true,get(){return val},set(newVal){//更改值得时候if(newVal===val){//设置的值和以前是一样的东西return}val = newVal//如果以后在获取值得时候,将刚才设置的值丢回去observe(newVal)}})}
}
function observe(data){if (typeof data !== 'object'){return }return new Observe(data)
}

①vue特点 不能新增不存在的属性 

    因为不存在的属性 没有 get和set,不能被监控

② 深度响应 因为每次赋予一个新对象时会给这个新对象增加数据劫持