mvvm实现原理总结(数据劫持,数据代理,订阅者发布者模式)

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。vue中采用的数据劫持+ 发布者订阅者模式

https://blog.csdn.net/dwfrost/article/details/85777900

1.要用到的基本属性属性--用法自己可以参考api

Object.defineProperty(obj,'name',{
      configurable:true,
      //writable:true,
      enumerable:false,
      // value: 'zpc',
      get(){
        return 'zpc'
      },
      set(val){
        console.log(val)
      },
    })

2.简单对象模拟observe实现数据劫持--实现对象的监视赋值

代码示例---还有如果对象内部属性还是对象的话就要循环监听
    var a = new Wrapper({ // 模拟new vue 构造示例对象
        el:'#app',
        data:{
            a:1
        }
    })

    function Wrapper (options={}){ // 定义构造函数,并进行参数绑定传递
        this.$option = options
        var data = this._data = option.data
        observe(data)
    }
    function observe(data){
        return new Observe(data)
    }
    function Observe(data){    // 定义Observe 构造函数,进行属性描述符设定监听赋值
        for (let key in data) {
            var val = data[key]
            Object.defineProperty(data,key,{
              configurable:true,
              enumerable:true,
              get(){
                return val
              },
              set(newval){
                if(newval == val){
                    return
                } else {
                    val = newval
                }
              },
            })  
        }
    }


此时打印console.log(a)
输出
{
    _data{a:1}
}

但是此时要的不是这个效果,是需要直接把a挂载在this上---需要实现数据代理

3.模拟实现数据代理

在上边的构造 函数实现数据劫持之后 添加数据代理
    function Wrapper (options={}){ // 定义构造函数,并进行参数绑定传递
        this.$option = options
        var data = this._data = option.data
        observe(data)     // 实现数据监视
=======================新添加=================================
        for (let key in data) { // 循环对象实现数据代理
            var val = data[key]
            Object.defineProperty(this,key,{
              configurable:true,
              enumerable:true,
              get(){
                return this._data[key]   // 此处就是相当于赋值操作this.a =  this._data[key]
              },
              set(newval){
                this._data[key] = newval
              },
            })  
        }
========================新添加=========================================
    }


1.vue的特点是不能新添加不存在的属性,不存在的属性没有set  get 方法
2.深度监视的原来,就是每次赋值内部对象添加数据代理和数据劫持

4.发布订阅模式--代码实现

发布订阅
function Dep (){
    this.subs = []
}
Dep.prototype.addSub = function(sub){
    this.subs.push(sub)
}
Dep.prototype.nitify = function(){
    this.subs.forEach(
        sub=>sub.update()
    )
}

实现watcher
function Watcher(fn){
    this.fn = fn
}
Watcher.prototype.update = function(){
    this.fn()
}

代码执行流程
let watcher = new Watcher(function(){
    console.logI('1')
})
let dep = new Dep()
dep.addSub(watcher)
dep.notify()   -将函数依次执行

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值