1。简介 本小节我们将介绍Vue渲染函数。包括什么是渲染函数、虚拟DOM、如何编写渲染函数。渲染函数是一个难点,通常在一些简单的项目中不会使用,在处理一些复杂的业务场景时,使用渲染函数往往可以达到事半功倍的效果。 通过本小节的学习我们可以掌握渲染函数的基本用法,如果同学们学完本小节之后对此还不是特别熟悉也没有关系,我们可以先将基础知识融会贯通,然后再对该知识点多加练习,相信同学们一定可以熟练掌握。2。基础 Vue推荐在绝大多数情况下使用模板来创建你的HTML。然而在一些场景中,你真的需要JavaScript的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。 让我们用一个简单的例子来学习,这个例子里render函数很实用。假设我们要生成一些带锚点的标题,标题的尺寸和锚点的地址需要通过属性传递,最终生成如下格式的DOM结构:h1Helloworld!h1 同学们肯定觉得这不是很简单吗,于是写下了如下示例: 实例演示!DOCTYPEhtmlhtmllangenheadmetacharsetUTF8metanameviewportcontentwidthdevicewidth,initialscale1。0metahttpequivXUACompatiblecontentieedgetitleDocumenttitleheadbodyHelloworld!anchoredheadingHelloworld!anchoredheadingHelloworld!anchoredheadingbodyhtml 运行案例可查看在线运行效果 代码解释:JS代码第233行,我们定义了组件的模板,通过vif根据传入的level来控制显示的标签元素。JS代码第3446行,我们定义了组件anchoredheading,接收level和href两个属性参数。HTML代码第24行,使用了组件anchoredheading。 上述代码虽然实现了功能,但是代码冗长,而且在每一个级别的标题中重复书写了。那么如何才能消除这些冗余的代码呢?我们来尝试使用render函数重写上面的例子: 实例演示!DOCTYPEhtmlhtmllangenheadmetacharsetUTF8metanameviewportcontentwidthdevicewidth,initialscale1。0metahttpequivXUACompatiblecontentieedgetitleDocumenttitleheadbodyHelloworld!anchoredheadingHelloworld!anchoredheadingHelloworld!anchoredheadingbodyhtml 运行案例可查看在线运行效果 通过render函数编写的组件看起来简单多了!同学们可能暂时还不太理解这段代码的含义,createElement是什么?这些参数又表示什么含义?我们先带着这些疑问继续往下学习。3。虚拟DOM Vue通过建立一个虚拟DOM来追踪自己要如何改变真实DOM。请仔细看这行代码:returncreateElement(h1,this。blogTitle) createElement到底会返回什么呢?其实不是一个实际的DOM元素。它更准确的名字可能是createNodeDescription,因为它所包含的信息会告诉Vue页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为虚拟节点(virtualnode),也常简写它为VNode。虚拟DOM是我们对由Vue组件树建立起来的整个VNode树的称呼。4。createElement参数 接下来你需要熟悉的是如何在createElement函数中使用模板中的那些功能。这里是createElement接受的参数:createElement({StringObjectFunction}一个HTML标签名、组件选项对象,或者resolve了上述任何一种的一个async函数。必填项。p,{Object}一个与模板中属性对应的数据对象。可选。{(详情见下一节)},{StringArray}子级虚拟节点(VNodes),由createElement()构建而成,也可以使用字符串来生成文本虚拟节点。可选。〔先写一些文字,createElement(h1,一则头条),createElement(MyComponent,{props:{someProp:foobar}})〕) 也就是说,我们通过createElement函数来递归创建我们的节点标签。5。深入数据对象 有一点要注意:正如vbind:class和vbind:style在模板语法中会被特别对待一样,它们在VNode数据对象中也有对应的顶层字段。该对象也允许你绑定普通的HTMLattribute,也允许绑定如innerHTML这样的DOM属性(这会覆盖vhtml指令)。{与vbind:class的API相同,接受一个字符串、对象或字符串和对象组成的数组class:{foo:true,bar:false},与vbind:style的API相同,接受一个字符串、对象,或对象组成的数组style:{color:red,fontSize:14px},普通的HTMLattributeattrs:{id:foo},组件propprops:{myProp:bar},DOM属性domProps:{innerHTML:baz},事件监听器在on属性内,但不再支持如von:keyup。enter这样的修饰器。需要在处理函数中手动检查keyCode。on:{click:this。clickHandler},仅用于组件,用于监听原生事件,而不是组件内部使用vm。emit触发的事件。nativeOn:{click:this。nativeClickHandler},自定义指令。注意,你无法对binding中的oldValue赋值,因为Vue已经自动为你进行了同步。directives:〔{name:mycustomdirective,value:2,expression:11,arg:foo,modifiers:{bar:true}}〕,作用域插槽的格式为{name:propsVNodeArrayVNode}scopedSlots:{default:propscreateElement(span,props。text)},如果组件是其它组件的子组件,需为插槽指定名称slot:nameofslot,其它特殊顶层属性key:myKey,ref:myRef,如果你在渲染函数中给多个元素都应用了相同的ref名,那么refs。myRef会变成一个数组。refInFor:true} 现在我们再来回顾上述的例子是不是很简单?首先,我们通过createElement函数创建h标签;它的子集是createElement函数创建的a标签;a标签的子集是通过this。slots。default获取的默认插槽。6。小结 本节,我们带大家学习了Vue渲染函数的使用方法。主要知识点有以下几点:使用渲染函数render代替template模板。虚拟DOM的定义,createElement函数的使用。