Vue底层架构及其应用(下)

栏目: 编程语言 · 发布时间: 5年前

内容简介:Vue的compiler部分负责对template的编译,生成render和staticRender函数,编译一次永久使用,所以一般我们在构建的时候就做了这件事情,以提高页面性能。执行render和staticRender函数可以生成VNode,从而为core提供这一层抽象。template ==》 AST ==》 递归ATS生成render和staticRender ==》VNode

| 导语  上一篇文章中,我们介绍了Vue底层架构的Core部分。这一片文章中我们将继续介绍Vue底层架构的Compiler与Platform以及它们的应用。

1. Compiler

Vue的compiler部分负责对template的编译,生成render和staticRender函数,编译一次永久使用,所以一般我们在构建的时候就做了这件事情,以提高页面性能。执行render和staticRender函数可以生成VNode,从而为core提供这一层抽象。

template ==》 AST ==》 递归ATS生成render和staticRender ==》VNode

(1)template转化成AST过程

先让我们来直观感受下AST,它描述了下面的template结构


 

// Vue模板


let template = `


<div class="Test" :class="classObj" v-show="isShow">


{{username}}:{{password}}


<div>


<span>hahhahahha</span>


</div>


<div v-if="isVisiable" @click="onClick"></div>

<div v-for="item in items">{{item}}</div>



</div>


`

Vue底层架构及其应用(下)

下面描述下template转为AST的简要过程:

1、 如果template是以 < 开始的字符串,则判断是评论,还是Doctype还是结束标签,或者是开始标签,这里只说处理开始和结束标签。

(1)如果是开始标签,则处理类似于下面字符串

<div class="Test" :class="classObj" v-show="isShow">

通过正则可以很容易解析出tag,所有属性列表,再对属性列表进行分类,分别解析出v-if,v-for等指令,事件,特殊属性等,template去除被解析的部分,回到 步骤1

(2)如果是结束标签,则处理类似于下面字符串,同样template去除被解析的部分,回到 步骤1

</div>

2、 如果不是第一种情况,说明是字符串,处理类似于下面的插值字符串或者纯文本,同样template去除被解析的部分,回到 步骤1

{{username}}:{{password}} 或者 用户名:密码

3 如果template为空,解析结束

(2)AST生成render和staticRender

主要是遍历ast(有兴趣的同学可以自己体验下,如:遍历AST生成还原上述模板,相信会有不一样的体验), 根据每个节点的属性拼接渲染函数的字符串 ,如:模板中有v-if="isVisiable",那么AST中这个节点就会有一个if属性,这样,在创建这个节点对应的VNode的时候,就会有 

(isVisiable) ? _c('div') : _e()

在with的作用下, isVisiable  的值决定了VNode是否生成。当然,对于一些指令,在编译时是处理不了的,会在生成VNode的时候挂载在VNode上,解析VNode时再进行进一步处理,比如v-show,v-on。

下面是上面模板生成的render和staticRender:


 

// render函数

(function anonymous() {

with (this) {

return _c('div', {

directives: [{

name: "show",

rawName: "v-show",

value: (isShow),

expression: "isShow"

}],

staticClass: "Test",

class: classObj

}, [_v("\n " + _s(username) + ":" + _s(password) + "\n "), _m(0), _v(" "), (isVisiable) ? _c('div', {

on: {

"click": onClick

}

}) : _e(), _v(" "), _l((items), function(item) {

return _c('div', [_v(_s(item))])

})], 2)

}

}

)

// staticRender

(function anonymous() {

with (this) {

return _c('div', [_c('span', [_v("hahhahahha")])])

}

}

)

其中this是组件实例,_c、_v分别用于创建VNode和字符串,像username和password是在定义组件时候传入的state并被挂载在this上。

2. Platform

platform模块与具体平台相关,我们可以在这里定义平台相关接口传入runtime和compile,以实现具体平台的定制化,因此为其他平台带来Vue能力,大部分工作在这里。

需要传入runtime的是 如何创建具体的平台元素,平台元素之间的关系以及如何append,insert,remove平台元素等,元素生成后需要进行的属性,事件监听等 。拿web平台举例,我们需要传入document.createElement,document.createTextNode,遍历vnode的时候生成HTML元素;挂载时需要的insertBefore;state发生变化导致vnode diff时的remove,append等。还有生成HTML元素后,用setAttribute和removeAttribute操作属性;addEventListener和removeEventListener进行事件监听;提供一些有利于web平台使用的自定义组件和指令等等

需要传入compile的是对 某些特殊属性或者指令在编译时的处理 。如web平台,需要对class,style,model的特殊处理,以区别于一般的HTML属性;提供web平台专用指令,v-html(编译后其实是绑定元素的innerHTML),v-text(编译后其实是绑定元素的textContent),v-model,这些指令依赖于具体的平台元素。

3. 应用

说了这么多,最终目的是为了 复用Vue的core和compile,以期在其他的平台上带来Vue或者类Vue的开发体验 ,前面也说了很多复用成功的例子,如果你要为某一平台带来Vue的开发体验,可以进行参考。大前端概念下,指不定那天,汽车显示屏,智能手表等终端界面就可以用Vue来进行开发,爽歪歪。那么,如何复用呢?当然我只说必选的,你可以定制更多更复杂的功能方便具体平台使用。

1. 定义vnode生成具体平台元素所需要的nodeOps,也就是元素的增删改查,对于web来说nodeOps是要创建,移动真正的dom对象,如果是其他平台,可自行定义这些元素的操作方法;

2. 定义vnode生成具体平台元素所需要的modules,对于web来说,modules是用来操作dom属性的方法;

3. 具体平台需要定义一个自己的$mount方法给Vue,挂载组件到已存在的元素上;

4. 还有一些方法,如isReservedTag,是否为保留的标签名,自定义组件名称不能与这些相同;mustUseProp,判定元素的某个属性必须要跟组件state绑定,不能绑定一个常量等等;

4. 总结

软件行业有一句名言,没有什么问题是添加一层抽象层不能解决的,如果有那就两层,Vue的设计正是如此(可能Vue也是借鉴别人的),compile的AST抽象层衔接了模板语法和render函数,经过VNode这个抽象层让core剥离了具体平台。

这篇文章的最终目的是为了让大家了解到 复用Vue源码的core和compile进行二次开发,可以做到为具体平台带来Vue或者类Vue的开发体验。当然,这只是一种思路,说不定哪天,Vue风格开发体验失宠了,那么我们也可以把这种思路应用到新开发风格上。

下面是广告时间

目前还有少量早鸟票火热销售中,两百不到面基大佬,犹豫犹豫多花两百,扫描下方二维码查看具体详情

Vue底层架构及其应用(下)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

嗨翻C语言

嗨翻C语言

[美]David Griffiths、[美]Dawn Griffiths / 程亦超 / 人民邮电出版社 / 2013-9 / 99.00

你能从这本书中学到什么? 你有没有想过可以轻松学习C语言?《嗨翻C语言》将会带给你一次这样的全新学习 体验。本书贯以有趣的故事情节、生动形象的图片,以及不拘一格、丰富多样的练 习和测试,时刻激励、吸引、启发你在解决问题的同时获取新的知识。你将在快乐 的气氛中学习语言基础、指针和指针运算、动态存储器管理等核心主题,以及多线 程和网络编程这些高级主题。在掌握语言的基本知识......一起来看看 《嗨翻C语言》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试