Vue.js实战学习笔记----Render函数

一、概述

(1)Vue.js 2.x与Vue.js 1.x最大的区别就在于2.x使用了Virtrual Dom(虚拟DOM)来更新DOM节点,提升渲染性能。

(2)写在template选项里的组件模板,在Vue.js编译时,会解析为Virtrual Dom。

(3)Render,是Vue.js用于实现Virtrual Dom的。

二、Virtrual Dom(虚拟DOM)

(1)React和Vue2都使用了Virtrual Dom技术,Virtrual Dom并不是真正意义上的DOM,而是一个轻量级的JavaScript对象,在状态发生变化时,Virtrual Dom会进行Diff计算,来更新只需要被替换的DOM,而不是全部重绘。

(2)与DOM操作相比,Virtrual Dom是基于JavaScript计算的,所以开销会小很多。

(3)正常的DOM节点在HTML中是这样的:

(4)用Virtrual Dom创建的JavaScript对象一般会是这样的

(5)Virtrual Dom运行过程

(6)vNode对象通过一些特定的选项描述了真实的DOM结构

(7)在Vue.js2中,Virtrual Dom就是通过一种VNode类表达的,每个DOM元素或组件都对应一个VNode对象,在Vue.js源码中是这样定义的:

(8)VNode主要可以分为如下几类。

(9)使用Virtrual Dom就可以完全发挥JavaScript的编程能力。

三、Render函数

(1)Render函数通过createElement参数来创建Virtrual Dom。

(2)使用对比

render函数写法:

四、createElement用法

(1)基本参数

createElement构成了 Vue Virtrual Dom 的模板,它有3个参数。

1)第一个参数必选,可以是一个HTML标签,也可以是一个组件或函数。

2)第二个是可选参数,数据对象,在template中使用。

3)第三个是子节点,也是可选参数,用法一致。

(2)第二个参数:数据对象

例子:

使用Render改写后的代码如下:

就此例而言,template的写法明显比Render写法要可读而且简洁,所以要在合适的场景使用Render函数,否则只会增加负担。

(3)约束

 所有的组件树中,如果VNode是组件或含有组件的slot,那么VNode必须唯一

1)错误示范

1.实例一,重复使用组件

2.实例二,重复使用含有组件的slot

这两个示例都期望在子节点内渲染出两个Child组件,也就是两个<p>text</p>节点,实际预览时只渲染出了一个,因为在这种情况下,VNode受到了约束。

2)对于重复渲染多个组件(或元素)的方法有很多,如下示例

1.组件

上例通过一个循环和工厂函数就可以渲染5个重复的子组件Child。

2.含有组件的slot

对于含有组件的slot,复用就要稍微复杂一点了,需要将slot的每个子节点都克隆一份。

在Render函数里创建了一个cloneVNode的工厂函数,通过递归将slot所有子节点都克隆了一份,并对VNode的关键属性也进行了复制。

(4)使用JavaScript代替模版功能

1)在Render函数中,不再需要Vue内置的指令,比如 v-if,v-for,当然,也没办法使用它们

2)无论要实现什么功能,都可以用原生JavaScript

3)v-if,v-else可以这样写

 上例直接使用JavaScript的 if 和 else 语句来完成逻辑判断。

4)v-for

5)使用JavaScript的 if 、else语句和数组map方法充分配合使用来渲染一个列表

首先是判断prop:list是否为空,如果是空,就渲染一个“列表为空”的<p>元素,如果不为空数组,那就把每一项作为<li>渲染,放在<ul>下。

对应的template

6)Render函数里也没有与v-model对应的API,需要自己来实现逻辑。

事实上,v-model就是prop:value和event:input组合使用的一个语法糖。

对应的template

7)对于事件修饰符和按键修饰符,基本也需要自己实现。

例子:

五、函数化组件

(1)Vue.js提供了一个functional的布尔值选项,设置为true可以使组件无状态和无实例,也就是没有data和this上下文。

(2)这样用render函数返回虚拟节点可以更容易渲染,因为函数化组件只是一个函数,渲染开销要小很多。

(3)使用函数化组件时,Render函数提供了第二个参数context来提供临时上下文。组件需要的data、props、slots、children、parent都是通过这个上下文来传递的,比如this.level要改写为context.props.level,this.$slots.default改写为context.children。

(4)示例

(5)函数化组件在业务中并不是很常用,而且也有其他类似的方法来实现,比如上例也可以用组件的is特性来动态挂载。总结起来,函数化组件主要适用于以下两个场景

  • 程序化地在多个组件中选择一个。
  • 在将children、props、data传递给子组件之前操作它们。

六、JSX

(1)使用Render函数最不友好的地方就是在模版比较简单时,写起来也很复杂,而且难以阅读出DOM结构,尤其当子节点嵌套较多时,嵌套的createElement就像盖楼一样一层一层延伸下去。例如

template

使用createElement改写后应该是:

(2)为了让Render函数更好地书写和阅读,Vue.js提供了插件babel-plugin-transform-vue-jsx来支持JSX语法

(3)JSX是一种看起来像HTML,但实际是JavaScript的语言扩展,它用更接近DOM结构的形式来描述一个组件的UI和状态信息,最早在React.js里大量应用。

比如上面的Render用JSX改写后的代码是:

注意:这里的render使用了ES2015的语法缩写了函数,参数h不能省略,否则使用时会触发错误。

(4)示例

上面的示例使用JSX后等于下面的代码:

(5)JSX仍然是JavaScript而不是DOM,如果你的团队不是JSX强驱动的,建议还是以模版template的方式为主,特殊场景(比如锚点标题)使用Render的createElement辅助完成。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值