Vue.js 中的 MVVM 模式

330 阅读1分钟

MVVM

MVVM 的关注点是操作 javascript,而不用关心如何操作 DOM

Model

数据层,没有其他成分

const data = {
    a: 1,
    b: 2
}

View

视图层,展示数据

<div>
    <span id="text" data-text="123"></span>
</div>

ViewModel

用来连接 Model 和 View,使得 Model 和 View 完全解耦。

Object.defineProperty()

对象的属性有两种类型,数据属性和访问器属性。这里要用的是访问器属性里面的 get 和 set 两个内部特征。通过 Object.defineProperty() 可以控制访问器的特征

当然 Object.defineProperties() 也是可以的

image.png

const person = {
  name: 'Jerry'
}

reactiveName = 'Jerry'

Object.defineProperty(person, 'name', {
  configurable: true,
  enumerable: true,
  get() {
    return reactiveName + '~'
  },
  set(value) {
    reactiveName = value + '123'
  }
})

// 改变属性,触发 set
person.name = 'Tom'

console.log(person.name) // Tom123~

Vue.js 中的双向绑定

Vue.js 的双向绑定便是利用 Object.defineProperty()MVVM 模式和发布订阅模式来实现的。

VM的初始化

ViewModel 的数据传入ViewModel。Model的数据比较简单就是一个对象。View 中的数据会抽取指令、方法和直接引用的变量。

利用 Object.defineProperty() 设置这些变量的 get set 方法。

发布订阅模式

订阅者便是这些变量,发布者是变量的 set

具体实现

data.png

Data: 每个组件实例都对应一个 Data,可以理解成 Model。在组件渲染过程中使用过的变量都会触发 Object.defineProperty()get

Watcher: 每个组件实例对应一个 Watcher。它会订阅这个组件渲染过程中的变量变化。当变量被修改触发 set,这时变量作为一个发布者通知 Watcher 这个订阅者

Component Render Function: 处理 Watcher 触发之后的数据逻辑