破酥 | C4iN
实现一个简单的MVVM-6

实现一个简单的MVVM-6

这部分我们整合之前的代码,从整体来实现MVVM。

在之前的学习中我们知道 Vue 使用的 MVVM 中包含三个主要部分:响应式、渲染器、编译器:

  • 响应式:核心是观察这些数据的变化,当这些数据发生变化以后,能通知到对应的观察者以实现相关的逻辑,涉及 MVVM 中的 View 和 View Model 的之间的双向绑定
  • 渲染器:用于将虚拟 DOM 转化为真实 DOM
  • 编译器:用于将模板编译为渲染函数

我们再拿出这张图:

render pipeline

当模板进入一个 MVVM 后,编译器会把模板编译为渲染函数,并建立响应联系。执行渲染函数后会生成模板对应的虚拟 DOM 。而后我们将虚拟 DOM 作为渲染器的输入,渲染器会将虚拟 DOM 转化为真实 DOM 并进行挂载。如果真实 DOM 已存在(即不是首次渲染),则会进行更新操作。而响应式系统检测到数据发生变化时,则会触发响应更新,重新触发渲染过程。

拿下面这段简单的模板来说:

1
2
3
4
<div>
<p class='test'>Test</p>
<p>MVVM</p>
</div>

编译后的结果:

1
2
3
function render() {
return h(div, [h(p, Test), h(p, MVVM)])
}

h函数

这里我们用到了h函数,h 其实代表的是 hyperscript 。它是 HTML 的一部分,表示的是超文本标记语言,当我们正在处理一个脚本的时候,在虚拟 DOM 节点中去使用它进行替换已成为一种惯例。其真正起作用的函数是之前提到的createVNode

Vue的官方定义:

返回一个“虚拟节点” ,其中包含向 Vue 描述它应该在页面上呈现哪种节点的信息,包括对任何子节点的描述。用于手动编写render

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function h(type: any, propsOrChildren?: any, children?: any) {
if (arguments.length = 2) {
if (typeof propsOrChildren === 'object' && !Array.isArray(propsOrChildren)) {
// 第二个 参数为单个VNode
if (isVNode(propsOrChildren)) {
return createVNode(type, [], [propsOrChildren])
}
return createVNode(type, propsOrChildren, [])
} else {
return createVNode(type, [], propsOrChildren)
}
} else {
if (isVNode(children)) {
children = [children]
}
return createVNode(type, propsOrChildren, children)
}
}

实现了h函数后,我们需要一个函数来作为整个MVVM框架的入口。

CreateApp

CreateApp作为 Vue 的启动函数,返回一个应用实例。

首先我们需要设计一个应用对象,作为响应式挂载对象ViewModel:

1

参考:

Vue3 (vue3js.cn)

Author:破酥 | C4iN
Link:https://c4in1.github.io/2024/09/05/MVVM/实现一个简单的MVVM-6/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可