从VUE双向数据绑定到MVVM模式

vue的双向数据绑定是vue框架不同于react的一大特点,对于其实现方式也是面试中常考的问题。
网上对于双向绑定的描述:

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点:
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者
在这里插入图片描述

上面的解释非常准确,但是对于初学者来说不容易理解,下面补充几点
1 object.defineproperty()
object.defineproperty()是ES5中的方法,有三个参数:属性所在的对象、属性的名字、描述符对象
ES5中,属性分为两种:数据属性和访问器属性。
数据属性有4个描述其行为的描述符:
① configurable,是否可通过delete删除,默认为false,定义后无法修改
② enumerable,是否可通过for-in遍历,默认为false,定以后无法修改
③ value:该属性对应的值,默认为undefined。
④ writable:当值为true时,value才能被赋值操作修改。默认为false。

let obj = {
    
    }
Object.defineProperty(obj,'age',{
    
    
    configurable:false,
    enumerable:true,
    value:10,
    writable:false
})

访问器属性也有4个描述符,前两个与数据属性相同:
① configurable,是否可通过delete删除,默认为false,定义后无法修改
② enumerable,是否可通过for-in遍历,默认为false,定以后无法修改
③ get():一个给属性提供getter的方法,读取属性时调用,默认为undefined。
④ set():一个给属性提供setter的方法,写入属性时调用,默认为undefined。

let obj = {
    
    }
let age
Object.defineProperty(obj,'age',{
    
    
    get:function(){
    
    
        return age
    },
    set:function(newVal){
    
    
        age = newVal
    }
})
obj.age    //undifine
obj.age = 10
obj.age     //10

数据描述符和访问器描述符不能同时存在
数据的拦截与监听正是通过Object.defineProperty()中get和set描述符实现的。

2 发布订阅模式和观察者模式
这部分推荐看下面这篇文章,讲的很明白观察者模式 vs 发布订阅模式

3 关于指令解析器Compile
先简单讲讲什么是指令,虽然Vue文档里说的指令是v-if,v-for等这种HTML的attribute,其实在Vue内部,只要是被Vue处理的dom上的东西都是指令,比如dom内容里的{ {a}},最终会转换成一个v-text的指令和一个textNode,而一个子组件也会生成指令,还有slot,或者是你自己在元素上写的attribute比如hello={ {you}}也会被编译为一个v-bind指令。我们看到,基本只要是涉及dom的(不是响应式的也包含在内,只要是vue提供的功能),不管是dom标签,还是dom属性、内容,都会被处理为指令。所以不要有指令就是attribute的惯性思维。
模板中每个指令/数据绑定都有一个对应的 watcher 对象,在计算过程中它把属性记录为依赖。之后当依赖的 setter 被调用时,会触发 watcher 重新计算 ,也就会导致它的关联指令更新 DOM。

一、MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。 如果前端没有框架,只使用原生的html+js,MVC模式可以这样理解。将html看成view;js看成controller,负责处理用户与应用的交互,响应对view的操作(对事件的监听),调用Model对数据进行操作,完成model与view的同步(根据model的改变,通过选择器对view进行操作);将js的ajax当做Model,也就是数据层,通过ajax从服务器获取数据。

二、MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。这里我们拿典型的MVVM模式的代表,Vue,Vue实例中的data相当于Model层,而ViewModel层的核心是Vue中的双向数据绑定,即Model变化时VIew可以实时更新,View变化也能让Model发生变化。整体看来,MVVM比MVC精简很多,不仅简化了业务与界面的依赖,还解决了数据频繁更新的问题,不用再用选择器操作DOM元素。因为在MVVM中,View不知道Model的存在,Model和ViewModel也观察不到View,这种低耦合模式提高代码的可重用性。

猜你喜欢

转载自blog.csdn.net/e1172090224/article/details/98632425
今日推荐