导航:首页 > 源码编译 > bue模板编译原理

bue模板编译原理

发布时间:2024-01-29 17:38:48

‘壹’ Vue - 组件和Vue.extend

在初学 Vue 的时候,都是利用 cdn 的方式在一个页面中导入 vue.js 的库文件.

接着,肯定就学到了组件开发.

当然,也是在单页面中.

API文档告诉我们

在后来,学到了使用 vue-cli 搭配 .vue 模板的方式开发组件.

好了,三种组件创建的方式说完了,且在各自的环境里都能够正常的运作.

在 Vue 开发中,所有的组件本质上都是由一个继承自 Vue 的构造函数创建的.

比如在注册局部组件时.

从视觉上,我们看到 TodoListComp 只是一个普通的 Object 对象.

直接赋值给了其他组件的 components 属性里.

然后,这个组件就成为了一个局部组件,并可以在注册了当前组件的内部去使用了.

那它在内部做了什么,导致这个普通的对象最后可以被当成是一个正常的组件来使用呢?

比如,普通对象上都没有 $el 之类的属性.丢给 components 之后,就啥都有了.

使用Vue.extend(options)会根据传入的options创建一个VueComponent的组件构造函数并返回.

既然使用 Vue.extend 会返回一个组件的构造函数.

那么我们就可以使用 new 这个返回的构造函数

并手动的 mount 并替换某个 dom 节点(就和 new App() 一样)

前面,我么已经知道了,所有的 vue 组件,不管是全局的还是局部的.

都是利用 Vue.extend 方法构建并返回出一个继承自 Vue 的组件构造函数.

这个函数接受一个满足了 Vue 组件属性项的普通的 Object 对象.

在.vue模板文件开发中,也不例外.

我们可以看看,在书写 .vue 模板文件时,我们到底在写什么?

我们写的是一个 .vue 文件.

并按照 <template></template> <script></script> ( 这里不关注 <style></style> 节点 ) 的格式编写 .vue 文件.

把它整合起来来看.

等价于

好了,继续回到 .vue 模板开发文件中.

在另外一个组件中,使用此组件时,我们会 import xxx from xxx.vue 并搭配 components:{ xxxx }

.vue 会被 webpack 中配置的 vue-loader 处理.这是我们已知的.

结合上述的判断, vue-loader 仅仅只是把 .vue 文件编译成了一个 vue.extend(options) 创建组件所需要的 options 普通对象而已.

既然 vue-loader 仅仅,只是把 .vue 模板文件编译成了一个 options 普通对象.

那么我们可以手动的使用 Vue.extends(options) 来获得这个组件对象的构造函数.

拿到此组件的构造函数,我们就可以在 组件 mounted 的时候,通过 new 的方式,挂在到 html 上了. (而无需去注册到 components,成为一个局部组件.直接把它当成一个自己熟悉的不能在熟悉的构造函数调用即可.)

既然我们已经知道:

我们完全可以直接使用 .js 文件的方式来创建 vue 组件,进而省略 .vue & vue-loader 这个执行的步骤.

此 .js 文件到处一个 vue 组件的构造函数.

在另外一个组件里

通过这样的原理,我们完全可以在HTML页面的任意地方,任意位置,任意的挂在我们自己的组件.并不一定必须使用.vue声明式组件的语法.

[ 码云地址 ]

‘贰’ Vue3基础-模板语法

如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号) 的文本插值。

并且我们前端提到过,data返回的对象是有添加到Vue的响应式系统 中,当data中的数据发生改变时,对应的内容也会发生更新。

当然,Mustache中不仅仅可以是data中的属性,也可以是一个JavaScript的表达式:

下面这种写法是语句不是表达式,所以是错误的:

v-once用于指定元素或者组件只渲染一次,当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过,该指令可以用于性能优化。

如果添加到父节点,那么所有的子节点也是只会渲染一次:

用于更新元素的 textContent,等价于"Mustache"语法,而且"Mustache"语法更灵活。

默认情况下,如果我们展示的内容本身是 html 的,那么vue并不会对其进行特殊的解析。如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来展示。

效果如下:

v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签。
跳过不需要编译的节点,加快编译的速度。

效果如下:

这个指令保持在元素上直到关联组件实例结束编译。

v-cloak 和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕,主要用于解决闪动问题,现在Vue3一般不会出现这个问题了。

<div> 不会显示,直到编译结束。

前面讲的一系列指令,主要是将值插入到模板内容中。但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。比如动态绑定a元素的href属性,动态绑定img元素的src属性。

绑定属性我们使用 v-bind: ,缩写 : ,用于动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。

v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍),在开发中,有哪些属性需要动态进行绑定呢?还是有很多的,比如图片的链接src、网站的链接href、动态绑定一些类、样式等等。

v-bind有一个对应的语法糖,也就是简写方式,在开发中,我们通常会使用语法糖的形式,因为更简洁。

注意 :Vue2 template模板中只能有一个根元素,Vue3 template模板中允许有多个根元素。

在开发中,有时候我们的元素class也是动态的,比如:当数据为某个状态时,字体显示红色,当数据另一个状态时,字体显示黑色。

绑定class有两种方式:对象语法,数组语法。

① 对象语法:我们可以传给 :class (v-bind:class 的简写) 一个对象,以动态地切换 class。

② 数组语法:我们可以把一个数组传给 :class,以应用一个 class 列表;

我们可以利用v-bind:style来绑定一些CSS内联样式,这是因为某些样式我们需要根据数据动态来决定,比如某段文字的颜色,大小等等。

CSS属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。

绑定style有两种方式:对象语法,数组语法。

① 对象语法:

② 数组语法: :style 的数组语法可以将多个样式对象应用到同一个元素上

在某些情况下,我们属性的名称可能也不是固定的。
前面我们无论绑定src、href、class、style,属性名称都是固定的,如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义,这种绑定的方式,我们称之为动态绑定属性。

如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢?非常简单,我们可以直接使用 v-bind 绑定一个对象。

如下:info对象会被拆解成div的各个属性。

前面我们绑定了元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互。
在前端开发中,我们需要经常和用户进行各种各样的交互,这个时候,我们就必须监听用户发生的事件,比如点击、拖拽、键盘事件等等。

在Vue中如何监听事件呢?使用v-on指令。接下来我们来看一下v-on的用法:

我们可以使用v-on来监听一下点击的事件:

v-on:click可以写成@click,是它的语法糖写法:

当然,我们也可以绑定其他的事件:

如果我们希望一个元素绑定多个事件,这个时候可以传入一个对象:

当通过methods中定义方法,以供@click调用时,需要注意参数问题:

情况一:如果该方法不需要额外参数,那么方法后的()可以不添加,并且方法的实现不用参数,直接就可以打印event。
情况二:如果需要同时传入某个参数和event时,可以通过$event传入事件,并且方法的实现必须按顺序写明参数。

@keyup.enter 代表enter键弹起的时候会调用onEnter方法,我们一般在方法里面获取输入的值:

在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断了。

Vue提供了下面的指令来进行条件判断:

下面我们来对它们进行学习。

v-if、v-else、v-else-if 用于根据条件来渲染某一块的内容,这些内容只有在条件为true时,才会被渲染出来,这三个指令与JavaScript的条件语句 if、else、else if 类似。

v-if 的渲染原理:v-if是惰性的,当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉,当条件为true时,才会真正渲染条件块中的内容。

因为v-if是一个指令,所以必须将其添加到一个元素上,但是如果我们希望切换的是多个元素呢?
如果此时我们使用div包裹,div会被渲染到界面上来,但是我们并不希望div被渲染,这个时候,我们可以选择使用template,template元素可以当做不可见的包裹元素,并且 v-if 可以添加到 template 上,但是最终template不会被渲染出来,类似于小程序中的block。

v-show和v-if的用法看起来是一致的,也是根据一个条件决定是否显示元素或者组件。

首先,在用法上的区别:

其次,本质的区别:

开发中如何进行选择呢?

在真实开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染。这个时候我们可以使用v-for来完成,v-for类似于JavaScript的for循环,可以用于遍历一组数据。

v-for的基本格式是 "item in 数组" ,数组通常是来自data或者prop,也可以是其他方式,item是我们给每项元素起的一个别名,这个别名可以自定来定义。

我们知道,在遍历一个数组的时候会经常需要拿到数组的索引,如果我们需要索引,可以使用格式 "(item, index) in 数组" ,注意顺序,数组元素项item在前面,索引项index在后面。

类似于v-if,你可以使用 template 元素来循环渲染一段包含多个元素的内容。
我们使用template来对多个元素进行包裹,而不是使用div来完成,因为div会被渲染,template不会被渲染。而且如果有ul,ul里面不推荐放div,只推荐放li。

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新,这些被包裹过的方法包括:

上面的方法会直接修改原来的数组,所以视图会跟着更新。但是某些方法不会替换原来的数组,而是会生成新的数组,比如 filter()、concat() 和 slice(),这时候我们可以通过重新赋值的方式触发视图更新,如下:

在使用v-for进行列表渲染时,我们通常会给元素或者组件绑定一个key属性。

这个key属性有什么作用呢?
我们先来看一下官方的解释:key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法,而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素。

官方的解释对于初学者来说并不好理解,比如下面的问题:
什么是新旧nodes,什么是VNode?
没有key的时候,如何尝试修改和复用的?
有key的时候,如何基于key重新排列的?

我们先来解释一下VNode的概念:
VNode的全称是Virtual Node,也就是虚拟节点。事实上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode。VNode的本质是一个JavaScript的对象。

如果我们不只是一个简单的div,而是有一大堆的元素,那么它们应该会形成一个VNode Tree。

我们先来看一个案例:这个案例是当我们点击按钮时会在li中间插入一个f。

我们可以确定的是,这次更新对于ul和button是不需要进行更新,需要更新的是我们li的列表。在Vue中,对于相同父元素的子元素节点并不会重新渲染整个列表,因为对于列表中 a、b、c、d它们都是没有变化的。在操作真实DOM的时候,我们只需要在中间插入一个f的li即可。

那么Vue中对于列表的更新究竟是如何操作的呢?
Vue事实上会对于有key和没有key会调用两个不同的方法,有key,那么就调用 patchKeyedChildren方法,没有key,那么就调用 patchUnkeyedChildren方法。

没有key的diff算法:

我们会发现上面的diff算法效率并不高,c和d来说它们事实上并不需要有任何的改动,但是因为我们的c被f所使用了,所有后续所有的内容都要一次进行改动,并且最后进行新增。

有key的diff算法:

所以我们可以发现,Vue在进行diff算法的时候,会尽量利用我们的key来进行优化操作,在没有key的时候我们的效率是非常低效的,在进行插入或者重置顺序的时候,保持相同的key可以让diff算法更加的高效。

‘叁’ 什么是vue

Vue.js是一个构建数据驱动的 web 界面的渐进式框架,是一个JavaScript MVVM库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用。

阅读全文

与bue模板编译原理相关的资料

热点内容
设备部门如何做好服务器 浏览:847
androido下载 浏览:476
神奇高量战法副图源码 浏览:828
汇编语言设计凯撒密码加密器 浏览:390
主次梁加密是加在哪里 浏览:662
模板匹配算法matlab 浏览:823
外地程序员去北京 浏览:22
安卓机换苹果12如何转移数据 浏览:418
互联网ntp服务器地址及端口 浏览:613
pdf到word转换器 浏览:267
飞行解压素材 浏览:498
51单片机指令用背吗 浏览:936
unityai算法 浏览:834
我的世界ice服务器如何打开pvp 浏览:975
c语言编程如何做标记 浏览:884
python数据分析实战pdf 浏览:985
u盘插入文件夹 浏览:918
华为amd云服务器 浏览:497
汉化编程卡是什么意思 浏览:128
python学习pdf 浏览:316