Vue.js 是通过数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调。
第一步 - 实现一个指令解析器(Compile)
初始化页面模版,包括基本的程序入口和DOM结构
1 |
|
处理组件配置项,将组件配置对象上的一些深层次属性放到 vm.$options 选项中,而在 Vue 源码中,初始化根组件时会进行选项合并操作,将全局配置合并到根组件的局部配置上
1 | // vue.js |
Compile
主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图
基本思路: 根据el
创建文档片段,nodeType
分别处理元素和文本节点,然后将解析后的文档片段附加到DOM树
1 | // compile.js |
工具类根据指令执行对应方法,集中处理DOM的CRUD操作
1 | // compileUtils.js |
{{msg}}
已经能出识别出,接下来就可以处理元素节点,例如与之等价的v-text="msg"
基本思路: 获取 node
节点的属性集合,识别自定义指令方法,删除指令属性
1 | export class Compile { |
补充 v-text
判断逻辑,并初始化赋值,v-html
实现逻辑同理
1 | const compileUtils = { |
数据响应式,处理自定义方法,并与 $data 对象进行关联
1 | // <button v-on:click="btnClick">Click</button> |
工具类新增 on
方法,负责DOM元素的事件绑定
1 | const compileUtils = { |
代理数据对象, this.msg
映射为 this.$data.msg
,通过defineProperty
数据劫持实现
1 | export default class Vue { |
处理 v-on:click
转 @click
的语法糖,有兴趣的小伙伴可以自己实现原生属性的识别和绑定~
1 | export class Compile { |
至此,我们已经基本实现了指令解析器的基础功能,包括指令与数据的绑定和事件处理,下一篇会讲解如何通过发布者-订阅者、数据劫持实现双向数据绑定