简单实现 MVVM 的订阅与数据劫持

MVVM 的设计模式非常多见,这里就不细说其出处了。

学生反馈一个面试题,说实现一个简单的 类似 vue 的 MVVM demo,自己尝试了一下,做个记录吧。

响应式原理

首先,先要理解 vue 的响应式原理,是数据劫持,即数据变化的时候,自动重新渲染相关页面。

其实这个需求是非常容易的,只要理解了 Object.defineProperty,大部分人都可以实现。

let data = {}, temp = ''

Object.defineProperty(data, key1, {
	set(value){
		console.log('this is a new value: ' + value)
		temp = value
		//some code like $('div').html(value) will automatic execute when key1 changed
	},
	get(){
		return temp
	}
})

data.key1 = 'Jack'
订阅模式

订阅器,我们可以简单的将其理解为一个队列,队列内都是即将在某个时刻执行的函数。

当然,为了方便查找,我们可以将其定义为一个对象类型,其中的每个属性,都是数组类型。

let Deep = {
  deepList: {},

  listen(key, fn){
    if(!this.deepList[key])
      this.deepList[key] = []
    
    this.deepList[key].push(fn)
  },

  trigger(){
    let key = Array.prototype.shift.call(arguments)

    let fnList = this.deepList[key]

    if(!key || !fnList || !fnList.length)
      return false
    
    for(let i=0, fn; fn = fnList[i++];) {
      fn.apply(this.arguments)
    }
  }
}
将订阅器与数据劫持绑定到一起

这里就是要实现,数据劫持发生后,去执行订阅器内相应的代码。

这样,就可以实现类似 vue 的,改变了某个 message,页面能同步渲染最新的结果。

let dataHijack = ({data, tag, datakey, selector}) => {
  let value = '', el = document.querySelector(selector);

  Object.defineProperty(data, datakey, {
    get(){
      return value
    },
    set(newVlaue){
      value = newVlaue
      Deep.trigger(tag, newVlaue)
    }
  })

  Deep.listen(tag, content=>{
    el.innerHTML = content
  })
}

这部分代码的逻辑十分简单

首先,通过Deep.listen 将页面标签与内容绑定到一起并放入到订阅器中
然后,在数据劫持中调用订阅器来实现更新html的功能

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍本套课程,大喵将带着大家手把手,编辑每一行代码,使用原生Javascipt及ES6的一些新特性,仿照目前国内非常流行的Vue框架的源码,开发构建一个属于你们自己的MVVM框架。让大家能够很清晰的学习及掌握,模板编译,数据绑定,响应式,文档碎片,观察者模式,发布订阅模式等等,这些Vue的核心知识点,都是怎么回事,它们之间有哪些关联,是如何进行双向数据绑定的等等。在使用vue2.x的核心Object.defineProperty构建完成框架后,大喵也会使用Vue3.0引入的数据劫持的Proxy新特性,来改造我们的MVVM框架,提升我们的框架性能。最终,大喵会手把手带着大家,从0开始配置webpack.config.js配置文件以及引入babel-loader,配置.babelrc文件,转换我们JS文件中的的ES6语法,最终压缩输出我们的MVVM框架库文件。课程目录01 手把手搭建MVVM框架 课程介绍、02 文件结构及基础类创建、03 入口类DamiaoMvvm实现、04 模板编译、05 元素节点解析编译、06 v-model 数据绑定逻辑梳理、07 v-model 数据绑定实现、08 模板文本编译逻辑梳理、09 模板文本渲染绑定、10 观察者Wather逻辑梳理、11 Wather 逻辑实现、12 Object.defineProperty()、13 defineProperty 小案例、14 observer数据劫持梳理、15 defineProperty数据劫持实现、16 发布订阅实现、17 Proxy 介绍与概述、18 使用Proxy改造MVVM框架、19 使用Proxy实现响应式、20 webpack 打包配置、21 babel 配置及文件输出、22 Mvvm Proxy 框架打包、23 Mvvm 框架搭建课程总结MVVM框架介绍MVVM是 Model-View-ViewModel 的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。在MVVM架构模式下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值