Vue.js render方法使用详解


Posted in Javascript onApril 05, 2017

前注:

版本限制:

Vue.js 2.0+
1.0无法使用

没耐心,只关心有什么用的,想知道其大概是获取什么东西后生成的,可以直接看结尾的总结

非使用render方法的情况

完整代码:

<!DOCTYPE html>
<html>
<head>
<title>Vue的render方法说明</title>
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child :level="1">Hello world!</child>
</div>
<script type="text/x-template" id="template">
<div>
<h1 v-if="level === 1">
<slot></slot>
</h1>
<h2 v-if="level === 2">
<slot></slot>
</h2>
<h3 v-if="level === 3">
<slot></slot>
</h3>
<h4 v-if="level === 4">
<slot></slot>
</h4>
<h5 v-if="level === 5">
<slot></slot>
</h5>
<h6 v-if="level === 6">
<slot></slot>
</h6>
</div>
</script>

<script type="text/javascript">
Vue.component('child', {
template: '#template',
props: {
level: {
type: Number,
required: true
}
}
})
new Vue({
el: "#app"
})
</script>
</body>
</html>

代码说明:

  • 最下面的new Vue方法很明显,是new了一个Vue的实例,挂载点是”#app”这个dom
  • Vue.component这部分代码,第一个参数表示注册了一个Vue的组件,标签名是child(即 <child> 标签会被替换);
  • 第二个参数中,template属性表示取找id=“template”的标签(另注,这个标签是script,或者是div,或者是template,或者是其他,没有影响),然后将这个标签作为组件的模板
  • props表示传递给这个组件的变量,通过标签中的v-bind:level这种形式传递变量level的值等于1。在这里的写法是限制变量类型为number,并且强制需要
  • slot表示内容分发,具体来说,就是把组件替换的源html标签里的内容(如 <child> 标签里面的内容,不包含 <child> 标签本身,这里是Hello world!),发在 <slot> 标签所在的位置(即放在 <h1>``````<h2> 这样的标签内)。
  • 如果还不理解,可以运行该段代码查看结果,或者去看vue的官方文档说明
  • 总的来说,顺序如下:注册一个组件,这个组件有模板,这个模板里有一个变量,变量的值通过父组件来传递,然后根据变量的值,通过v-if命令显示对应的html标签内容,然后在父组件里使用这个组件,让子组件显示需要显示的内容。

这样的代码有一个缺陷,就是需要写大量重复的代码,如从 <h1> ~ <h6> 共6种情况。如果这样的模板比较复杂,比如 <hx> 标签里还有很多其他内容,显然会让人十分困扰,既不美观也不好用。

使用render方法的情况

解决办法就是render方法,全部代码如下:

<!DOCTYPE html>
<html>
<head>
<title>Vue的render方法说明</title>
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child v-bind:level="2">Hello world!</child>
</div>
<script type="text/javascript">
Vue.component('child', {
render: function (createElement) {
return createElement(
'h' + this.level, // tag name 标签名称
this.$slots.default // 子组件中的阵列
)
},
props: {
level: {
type: Number,
required: true
}
}
})
new Vue({
el: "#app"
})
</script>
</body>
</html>

代码说明:

1、这里的代码和上面区别之处有两点:

其一,没有显式的模板内容,而是通过render方法生成;
其二,使用了createElement方法

2、关于createElement方法,他是通过render函数的参数传递进来的,这个方法有三个参数,

第一个参数主要用于提供dom的html内容,类型可以是字符串、对象或函数。比如”div”就是创建一个 <div>标签

第二个参数(类型是对象)主要用于设置这个dom的一些样式、属性、传的组件的参数、绑定事件之类,具体可以参考 官方文档 里这一小节的说明

第三个参数(类型是数组,数组元素类型是VNode)主要用于说是该结点下有其他结点的话,就放在这里。

比如说,有需要分发的标签 <slot>,则通过 this.$slots.default 来获得,或许还有其他组件之类,可能需要被使用的,应该也是放在这里。

个人初步理解是,在原本被替换的地方,例如例上面代码中的 <child> 标签,在其下的每个次一级标签为一个元素,放在 this.$slots.default这个数组中,例如上面的话,这个数组只有一个元素,但是以下代码:

<child v-bind:level="2"><div>Hello</div><div> world!</div></child>

这个数组中则有两个元素,分别是 <div>Hello</div> 和 <div> world!</div>,例如 this.$slots.default[0] 则表示第一个标签。

另外,假如这2个元素中间有空格、换行符之类,那么数组中则有三个元素,那个空格、换行符则为第二个元素。这个属性有点类似dom的 childNodes属性,不是单纯以标签才算作子节点的。(但注意,不是完全相同)

有时候,我们可能想在里面添加其他的组件,例如将abc组件注册在里面。那么,我们首先要注册这个abc组件,然后将abc组件在数组里通过createElement来创建标签,只有通过这样的方式创建的abc标签,才能被abc组件使用。单纯输入字符串 "<abc></abc>" 这样是不可以的。

如以下代码是可行的:(在通过render方法生成的模板中添加别的组件)

<!DOCTYPE html>
<html>
<head>
<title>Vue的render方法说明</title>
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child v-bind:level="2">
<div>Hello</div><div> world!</div>
</child>
</div>
<script>
Vue.component('abc', {
template: "<div>abc</div>"
})

Vue.component('child', {
render: function (createElement) {
console.log(this.$slots)
return createElement(
'h' + this.level, // tag name 标签名称
[this.$slots.default[0], createElement("abc"), this.$slots.default[1]] // 子组件中的阵列
)
},
props: {
level: {
type: Number,
required: true
}
}
})

new Vue({
el: "#app"
})
</script>
</body>
</html>

显示结果是:

Hello
abc
world!

最后,如果想将原有内容全部使用(而不是只取部分标签),那么直接使用 this.$slots.default 作为第三个参数即可,他本身就是一个数组。

3、总而言之,createElement方法的作用就是动态的创建一个dom用于被render函数渲染,其中参数二和参数三可以选择性省略,参数二用于设置dom的样式、属性、事件等,参数三用于设置分发的内容,包括新增的其他组件。

粗略理解的话,可以理解为:createElement( 标签名, 标签属性, 标签里的内容)

这样的话,我们就有了一个组件的模板所需要的全部内容了

总结

1、render方法的实质就是生成template模板;

2、通过调用一个方法来生成,而这个方法是通过render方法的参数传递给他的;

3、这个方法有三个参数,分别提供标签名,标签相关属性,标签内部的html内容

4、通过这三个参数,可以生活曾一个完整的模板。

备注:

1、render方法可以使用JSX语法,但需要Babel plugin插件;

2、render方法里的第三个参数可以使用函数来生成多个组件(特别是如果他们相同的话),只要生成结果是一个数组,且数组元素都是VNode即可

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js getElementsByTagName的简写方式
Jun 27 Javascript
js 跳出页面的frameset框架示例介绍
Dec 23 Javascript
JavaScript实现简单的数字倒计时
May 15 Javascript
JS动态插入并立即执行回调函数的方法
Apr 21 Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
Feb 12 Javascript
jQuery简单实现向列表动态添加新元素的方法示例
Dec 25 jQuery
详解JS数值Number类型
Feb 07 Javascript
angularjs数组判断是否含有某个元素的实例
Feb 27 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
Jul 20 Javascript
Angular2实现的秒表及改良版示例
May 10 Javascript
如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)
Jun 18 jQuery
js实现简单掷骰子小游戏
Oct 24 Javascript
self.attachevent is not a function的解决方法
Apr 04 #Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
Apr 04 #Javascript
Vue.js实战之使用Vuex + axios发送请求详解
Apr 04 #Javascript
Vue.js实战之组件的进阶
Apr 04 #Javascript
关于axios返回空对象的问题解决
Apr 04 #Javascript
jQuery自定义图片上传插件实例代码
Apr 04 #jQuery
jQuery使用unlock.js插件实现滑动解锁
Apr 04 #jQuery
You might like
介绍php设计模式中的工厂模式
2008/06/12 PHP
Zend 输出产生XML解析错误
2009/03/03 PHP
简单的php写入数据库类代码分享
2011/07/26 PHP
PHP中防止直接访问或查看或下载config.php文件的方法
2012/07/07 PHP
基于PHP中的常用函数回顾
2013/07/11 PHP
PHP XML和数组互相转换详解
2016/10/26 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
js获取height和width的方法说明
2013/01/06 Javascript
JQuery实现鼠标滑过显示导航下拉列表
2013/09/12 Javascript
jquery做的一个简单的屏幕锁定提示框
2014/03/26 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
2014/08/16 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
JQuery标签页效果的两个实例讲解(4)
2015/09/17 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
2016/11/05 Javascript
基于Javascript倒计时效果
2016/12/22 Javascript
详解nodejs异步I/O和事件循环
2017/06/07 NodeJs
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
2017/12/29 Javascript
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
2019/04/30 Javascript
JavaScript数组去重实现方法小结
2020/01/17 Javascript
[06:21]2014DOTA2国际邀请赛 庆祝VG首阶段领跑;B叔为挣牛排半夜整理情报
2014/07/13 DOTA
python网络编程之读取网站根目录实例
2014/09/30 Python
Python输出汉字字库及将文字转换为图片的方法
2016/06/04 Python
浅析Python3爬虫登录模拟
2018/02/07 Python
Python代码块批量添加Tab缩进的方法
2018/06/25 Python
Python实现基于C/S架构的聊天室功能详解
2018/07/07 Python
Python Web框架之Django框架cookie和session用法分析
2019/08/16 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
印度购物网站:TATA CLiQ
2017/11/23 全球购物
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
工业自动化专业毕业生推荐信
2013/11/18 职场文书
大众服装店创业计划书范文
2014/01/01 职场文书
村官工作鉴定评语
2014/01/27 职场文书
班组长安全工作职责
2014/07/15 职场文书
2014年信用社工作总结
2014/11/25 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
2016年小学“公民道德宣传日”活动总结
2016/04/01 职场文书