第8章 渲染函数_第1页
第8章 渲染函数_第2页
第8章 渲染函数_第3页
第8章 渲染函数_第4页
第8章 渲染函数_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章渲染函数

课程目标需要有JavaScript的完全编程的能力了解createElement方法及参数使用使用渲染函数实现v-if,v-for,v-model及slot插槽,作用域插槽。2课程内容

什么是渲染函数使用渲染函数createElement方法VNodes必须唯一使用JavaScript代替模板功能38.1渲染函数

4Vue渲染函数就是Render函数,Render函数会返回一个VNode,VNode就是一个JavaScript对象,DOM的映射。要想理解Vue渲染函数,首先需要了解Vue的虚拟DOM。

8.1.1

从虚拟DOM了解Vue渲染函数

虚拟DOM的工作是将浏览器DOM节点的所有信息映射到一个JavaScript对象上。因为JavaScript本身是很快的,但是DOM操作本身很慢。如果把DOM的信息映射到JavaScript对象上,至少应当获取DOM信息时不需要遍历DOM,而DOM的操作一直是JavaScript优化的重点。使用虚拟DOM,程序员不需要自己操作DOM,关于DOM的操作都会由虚拟DOM完成,而虚拟DOM一定会以最优方案来进行操作,所以虚拟DOM的重点是构建一个浏览器DOM的信息拷贝树,拷贝树里必须包含所有DOM节点的拷贝节点,这个拷贝节点叫作VNode。

58.1渲染函数

6关于虚拟DOM的好处还有一个就是Vue会把所有的DOM操作缓存到一个队列,这种在缓冲时去除重复数据,可以避免不必要的计算和DOM操作非常重要。如何创建VNode,可以自己创建VNode,然后Vue将程序员创建的VNode更新到真实DOM上,这样更自由权限更大,创建VNode的方法createElement。8.1.2为什么使用渲染函数通过下面的案例发现:level显示不同级别的标题中插入锚定元素,需要重复使用<slot></slot>来实现内容分发。虽然模板在大多数组件中都非常好用,但是这里并不简洁,为了解决这个问题,Vue提供了渲染函数

78.<divid="app">9. <h1>10. <aname="hello-world"href="#hello-world">11. Helloworld!12. </a>13. </h1>14. <anchored-heading:level="1">15. <aname="title"href="#title">16. Helloworld!17. </a>18. </anchored-heading>19. </div>20. <scripttype="text/x-template"id="anchored-heading-template">21. <div>22. <h1v-if="level===1">23. <slot></slot>24. </h1>25. <h2v-if="level===2">26. <slot></slot>27. </h2>28. <h3v-if="level===3">29. <slot></slot>30. </h3>31. <h4v-if="level===4">32. <slot></slot>33. </h4>34. <h5v-if="level===5">35. <slot></slot>36. </h5>37. <h6v-if="level===6">38. <slot></slot>39. </h6>40. </div>41. </script>42. <scriptsrc="../js/vue.js"></script>43. <script>44. Vponent('anchored-heading',{45. template:'#anchored-heading-template',46. props:{47. level:{48. type:Number,49. required:true50. }51. }52. })53. newVue({54. el:'#app'55. })56. </script>8.1.3

什么是渲染函数Vue推荐在绝大多数情况下使用template来创建HTML。然而在一些场景中,需要JavaScript的完全编程的能力,这就需要使用render函数。

8Vue.component('组件名',{render:function(createElement){returncreateElement(参数)}})【例8-2】使用渲染函数

9<metacharset="UTF-8">.<title>斤斗云在线课堂</title></head><body><divid="app"><h1><aname="hello-world"href="#hello-world">Helloworld!</a></h1><anchored-heading:level="1"><aname="title"href="#title">Helloworld!</a></anchored-heading><anchored-heading:level="2"><aname="title"href="#title">Helloworld!</a></anchored-heading><anchored-heading:level="3"><aname="title"href="#title">Helloworld!</a></anchored-heading>10<scriptsrc="../js/Vue.js"></script><script>Vue.component('anchored-heading',{template:'#anchored-heading-template',render:function(createElement){returncreateElement('h'+this.level,//tagname标签名称this.$slots.default//子组件中的阵列)},props:{level:{type:Number,required:true})newVue({el:'#app'})</script></body></html>在组件中使用props,父组件传递参数level给子组件,同时还做了props验证,level必须是Number类型。不再使用slot插槽向组件中分发内容,使用$slots.default把子元素显示出来。8.2createElement方法createElement方法,通过render函数的参数传递进来。一般情况下如:createElement(tag,{},[])或者createElement(tag,{},String),不过接收的参数不一样,后面两个参数都是可选的,总共有三个参数。118.2.1createElement参数【例8-3】createElement方法必须参数-{String|Object|Function}12<elem></elem></div><script>

Vue

.

component(‘elem’,

{

render:

function(createElement)

{

return

createElement(‘div’);//一个HTML标签字符/*return

createElement({

template:

‘<div></div>’

//组件选项对象});*/

/*varfunc

=

function()

{

return

{template:

<div></div>’}

};

return

createElement(

func());//一个返回HTML标签字符或組件选项对象的函数*/}

});

new

Vue({

el:

'

#app

'

});</script></

body></html>【例8-4】createElement方法第二个参数

-{Object}13

<meta

charset="UTF-8"><titlexrender</title>

<script

src-"-./js/Vue.

js“></script><

/head><body>

<div

id="app">

<elem></elem></div><script>

Vue.

component(‘elem’,

{

render:

functi

on(

createElement)

{

return

createE

lement(‘div’,

{'class':

{

foo:

true,bar:

true

},

style:

{

color:

'gray',fontSize:’

14px'

},

attrs:

{

8.2.2实例化Vue对象、

运行后在页面上渲染了一个div标签,并且增加了id、class属性,style行内样式及innerHTML的内容如图8-5所示。14【例8-5】createElement方法第三个参数-{String|Array}15<body>

<div

id="

app">

<elem></elem></div><script>

Vue

.

component('elem',

(

render:

function(

createElement)

{

var

self

=

this;

return

createElement(

‘div’,

[//由createElement函数构建而成的数組

createElement(‘h1’,

‘主标’

),//createElement函数返回Vnode对象createElement(‘h2’,

‘副标'

)

]);

};

new

Vue({

el:

'

#app'

});</script></body>

16运行后在页面上渲染了一个<div>标签,并渲染了两个标题对象<h1>、<h2>如图8-6所示。

使用模板与Render函数对比

17

模板写法更简单、可读。

模板开发效率是第一位。模板使用webpack编译,模板都会被预编译为Render函数。8.2.3

VNodes必须唯一官方提示VNodes必须唯一,就是同一个VNode只能用在一个地方。这里的myParagraphVNode,被使用于div中的两个VNode,这种用法是不行的,要想使用只能创建两个相同的VNode对象,而不是这样指向同一个VNode对象。18render:function(createElement)(varmyParagraphVNode.createElement('p','hi')returncreateElement('div',[myParagraphVNode,myParagraphVNode])8.3使用JavaScript代替模板功能在使用Vue模板时在模板中灵活使用v-if、v-for、v-model等指令和<slot>插槽。但在Render函数中是没有提供专用的API。如果在Render函数中使用这些,需要使用原生的JavaScript来实现

198.3.1v-if和v-for

在Render函数中可以使用if/else和map来实现template中的v-if和v-for。换成Render函数,可以这样写:20<ul

v-if="items

.length">

<li

v-for="item

in

items">{{item

}}</li></ul>

<p

v-else>No

items

found.</p>Vue.

component('

item-list',

{

props:

['items

'],

render:

function

(

createElement

){

if

(this.

items.

length)

{

return

createElement('ul',

this.

items

.

map((item)

=>{

return

createEl

ement(

'

item"

))))

}else

{

return

createElement(

'p',

'No

items

found.

"

)

}}}})8.3.2v-model【例8-5】使用Render函数实现v-model指令<body><divid="app"><el-input:name="name"@input="val=>name=val"></el-input><div>您学习的平台是:{{name}}</div></div><script>Vue.component('el-input',{render:function(createElement){varself=this;returncreateElement('input',{domProps:{value:self.name},on:{input:function(event){self.$emit('input',event.target.value);.}}}),实现数据双向绑定8.3.3slot插槽【例8-6】this.$slots获取VNodes列表中的静态内容<body><divid="app"><blog-post><h1slot="header"><span>可以从this.$slots获取VNodes列表中的静态内容</span></h1><p>这里是一个段落</p><pslot="footer">版权所有</p><p>这里是另一个段落</p></blog-post></div><script>Vue.component('blog-post',{render:function(createElement){varheader=this.$slots.header,//返回由VNode组成的数组body=this.$slots.default,footer=this.$slots.footer;returncreateElement('div',[createElement('header',header),createElement('main',body),createElement('footer',footer)])}});newVue({el:'#app'this.$slots.header获取header插槽的值,this.$slots.default获取插槽中的默认值8.3.4作用域插槽【例8-7】this.$scopedSlots作用域插槽<body><divid="app"><ele><templatescope="props"><

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论