了解VUE的render函數(shù)的使用
Vue 推薦在絕大多數(shù)情況下使用 template 來(lái)創(chuàng)建你的 HTML。然而在一些場(chǎng)景中,你真的需要 JavaScript 的完全編程的能力,這就是 render 函數(shù),它比 template 更接近編譯器。 在 HTML 層, 我們決定這樣定義組件接口:通過(guò)傳入不同的level 1-6 生成h1-h6標(biāo)簽,和使用slot生成內(nèi)容
<div id="div1"> <child :level="1">Hello world!</child> </div> <script type="text/x-template" id="child-template"> <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> </script> <script type="text/javascript"> /** * 全局注冊(cè)child組件,注意template如果值以 # 開(kāi)始,則它用作選項(xiàng)符,將使用匹配元素的 innerHTML 作為模板。常用的技巧是用 <script type="x-template"> 包含模板,這樣的好處是html不會(huì)渲染里面的內(nèi)容 * 這里使用template不是最好的選擇, * 一、代碼冗長(zhǎng) * 二、在不同的標(biāo)題插入內(nèi)容需要重復(fù)使用slot * 三、由于組件必須有根元素,所以標(biāo)題和內(nèi)容被包裹在一個(gè)無(wú)用的div中,比如<div><h1>hello world</h1></div> */ Vue.component('child', { template: '#child-template', props: { level: { type: Number, required: true } }, data: function() { return { a: 1 } } }) new Vue({ el:"#div1" }) </script>
我們嘗試使用render函數(shù)實(shí)現(xiàn)上面的例子,注意使用render函數(shù),template 選項(xiàng)將被忽略。 createElement接收3個(gè)參數(shù):
第一個(gè)參數(shù)可以是HTML標(biāo)簽名,組件或者函數(shù)都可以;此參數(shù)是必須的;
第二個(gè)為數(shù)據(jù)對(duì)象{Object}(可選);
第三個(gè)為子節(jié)點(diǎn){String | Array}(可選),多個(gè)子節(jié)點(diǎn)[createElement(tag1),createElement(tag2)]。
<div id="div1"> <child :level="1"> Hello world! </child> <child :level="2"> <!-- 將不會(huì)被顯示 --> <span slot="footer">span</span> <p slot="header">header slot<span>span</span></p> </child> </div> Vue.component('child', { render: function(createElement) { console.log(this.$slots); return createElement( 'h'+ this.level, // tagName標(biāo)簽名稱 { // 為每個(gè)h標(biāo)簽設(shè)置class 'class': { foo: true, bar: false }, // 最終被渲染為內(nèi)聯(lián)樣式 style: { color: 'red', fontSize: '14px' }, // 其他的html屬性 attrs: { id: 'foo', 'data-id': 'bar' }, // DOM屬性 domProps: { // innerHTML: 'from domProps', }, // 事件監(jiān)聽(tīng)器基于 "on" // 所以不再支持如 v-on:keyup.enter 修飾器 on: { click: this.clickHandler }, // ... }, // 你可以從this.$slots獲取VNodes列表中的靜態(tài)內(nèi)容 // $slots.default用來(lái)訪問(wèn)組件的不具名slot // 當(dāng)你可能需要具名slot的時(shí)候需要指定slot的name, this.$slots.header [this.$slots.default] ) }, template: '<div v-if="level===1"><slot></slot></div>', // 將被忽略 props: { level: { type: Number, required: true } }, methods: { clickHandler: function() { console.log('clickHandler') } } }) new Vue({ el:"#div1" })
我們現(xiàn)在可以完成這樣的組件
<h1> <a name="hello-world" href="#hello-world" rel="external nofollow" > Hello world! </a> </h1> // 遞歸函數(shù)獲得helloworld文本 function getChildrenTextContent(child) { return child.map(function(node) { return node.children? getChildrenTextContent(node.children) : node.text }).join('') } Vue.component('child',{ render: function(createElement) { var hello_world = getChildrenTextContent(this.$slots.default) .toLowerCase() .replace(/\W+/g,'-') .replace(/^\-|\-$/g,''); return createElement( 'h'+ this.level, {}, [ // 創(chuàng)建一個(gè)a標(biāo)簽,設(shè)置屬性,并設(shè)置a標(biāo)簽的子節(jié)點(diǎn) createElement('a',{ attrs: { name: hello_world, href: '#' + hello_world } },this.$slots.default) ] ) }, props: { level: { type: Number, required: true } } }) new Vue({ el:"#div1" })
注意VNode的唯一性,這里兩個(gè)VNode指向同一引用是錯(cuò)誤的,如果要重復(fù)創(chuàng)建多個(gè)相同元素/組件,可以使用工廠函數(shù)實(shí)現(xiàn)
<div id="div1"> <child :level="1"> Hello world! </child> </div> Vue.component('child',{ // render: function(createElement) { // var myParagraphVNode = createElement('p','hello') // return createElement('div', // [myParagraphVNode, myParagraphVNode] // ) // }, render: function(createElement) { return createElement('div', Array.apply(null, {length:20}).map(function() { return createElement('p','hello') }) ) }, props: { level: { type: Number, required: true } } }) new Vue({ el:"#div1" })
使用javascript代替模板功能,某些api要自己實(shí)現(xiàn)
①使用if/else代替v-if
②使用map代替v-for
Vue.component('child',{ render: function(createElement) { if (this.lists.length) { return createElement('ul',this.lists.map(function() { return createElement('li','hi') })) } else { return createElement('p','no lists') } }, props: { level: { type: Number, required: true } }, data: function() { return { lists: [1,2,3] } } }) // render函數(shù)中沒(méi)有與v-model相應(yīng)的api - 你必須自己來(lái)實(shí)現(xiàn)相應(yīng)的邏輯: Vue.component('child-msg',{ render: function(createElement) { var self = this; return createElement('div', [ createElement('input',{ 'on': { input: function(event) { self.value = event.target.value; } } }),createElement('p',self.value) ]) }, props: { level: { type: Number, required: true } }, data: function() { return { value: '' } } }) new Vue({ el:"#div1" })
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue組件傳值異步問(wèn)題子組件拿到數(shù)據(jù)較慢解決
這篇文章主要為大家介紹了Vue組件傳值異步中子組件拿到數(shù)據(jù)較慢的問(wèn)題解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08關(guān)于element-ui?單選框默認(rèn)值不選中的解決
這篇文章主要介紹了關(guān)于element-ui?單選框默認(rèn)值不選中的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09如何處理vue router 路由傳參刷新頁(yè)面參數(shù)丟失
這篇文章主要介紹了如何處理vue router 路由傳參刷新頁(yè)面參數(shù)丟失,對(duì)vue感興趣的同學(xué),可以參考下2021-05-05Vue?echarts實(shí)例項(xiàng)目商家銷量統(tǒng)計(jì)圖實(shí)現(xiàn)詳解
Echarts,它是一個(gè)與框架無(wú)關(guān)的?JS?圖表庫(kù),但是它基于Js,這樣很多框架都能使用它,例如Vue,估計(jì)IONIC也能用,因?yàn)槲业牧?xí)慣,每次新嘗試做一個(gè)功能的時(shí)候,總要新創(chuàng)建個(gè)小項(xiàng)目,做做Demo2022-09-09談?wù)勔騐ue.js引發(fā)關(guān)于getter和setter的思考
最近因?yàn)楣镜男马?xiàng)目決定使用Vue.js來(lái)做,但在使用的過(guò)程中發(fā)現(xiàn)了一個(gè)有趣的事情,因?yàn)榘l(fā)現(xiàn)的這個(gè)事情展開(kāi)了一些對(duì)于getter和setter的思考,具體是什么下面通過(guò)這篇文章來(lái)一起看看吧,有需要的朋友們可以參考學(xué)習(xí)。2016-12-12Vant?UI中van-collapse下拉折疊面板默認(rèn)展開(kāi)第一項(xiàng)的方法
之前做項(xiàng)目的時(shí)候,使用了Collapse折疊面板,下面這篇文章主要給大家介紹了關(guān)于Vant?UI中van-collapse下拉折疊面板默認(rèn)展開(kāi)第一項(xiàng)的相關(guān)資料,需要的朋友可以參考下2022-03-03Ant design vue中的聯(lián)動(dòng)選擇取消操作
這篇文章主要介紹了Ant design vue中的聯(lián)動(dòng)選擇取消操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10vue+element 多個(gè)相同的select不允許重復(fù)選擇問(wèn)題
這篇文章主要介紹了vue+element 多個(gè)相同的select不允許重復(fù)選擇問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-07-07