十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
Vue中怎么動(dòng)態(tài)添加模板,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
例如要做一個(gè)類 select 的組件,用戶傳入 options 數(shù)據(jù),通過(guò) value prop 獲取選中值,最基本的原型如下。
Vue.component('XSelect', { template: ``, props: ['value','options'] })
如果此時(shí)需要增加一個(gè) API 支持讓用戶自定義 option 部分的模板。此處用 slot 并不能解決問(wèn)題。
通過(guò) $options.template 修改
通過(guò)打印組件對(duì)象可以獲得一個(gè)信息,在$options里定義了一個(gè) template 屬性,寫(xiě)在 template 標(biāo)簽里的模板,最終編譯后也會(huì)在 $options.template 里。通過(guò)文檔的生命周期 可以得知,在 created 的時(shí)候, 實(shí)例已經(jīng)結(jié)束解析選項(xiàng), 但是還沒(méi)有開(kāi)始 DOM 編譯 也就是說(shuō),如果用戶通過(guò) prop 的數(shù)據(jù)我們可以獲得,但是模板其實(shí)還沒(méi)有渲染成 DOM。經(jīng)過(guò)測(cè)試,在created
修改this.$options.template
是可以改變最終生成的 DOM 的,同時(shí)也能拿到 props 的內(nèi)容。
那么我們可以修改下代碼,使其支持自定義模板
Vue.component('XSelect', { props: [ 'value', 'options', { name: 'template', default:'' } ], created() { varoptionTpl =this.template this.$options.template =`` } })${optionTpl}
用戶使用是就可以傳入模板了
可能存在的問(wèn)題
我們知道 Vue 在內(nèi)部幫我們做了許多優(yōu)化,但是在這里可能會(huì)由于某些優(yōu)化導(dǎo)致動(dòng)態(tài)拼接的模板無(wú)法渲染成功。例如這里我們不使用 v-for 而是手工遍歷 options 生成需要的 HTML
consttpl = options.map(opt =>`${this.optionTpl}`) this.$options.template =`${tpl}`
這里會(huì)導(dǎo)致一個(gè) BUG,如果一個(gè)頁(yè)面有多個(gè) x-select 組件,并且 options 長(zhǎng)度不一樣,會(huì)導(dǎo)致長(zhǎng)的 options 的組件后面幾個(gè)選項(xiàng)渲染不出來(lái)。究其原因是 Vue 會(huì)幫我們緩存模板編譯結(jié)果。翻看代碼可以找到 vue/src/instance/internal/lifecycle.js 里有做優(yōu)化,同時(shí)提供的 _linkerCachable 本意是給 內(nèi)聯(lián)模板 使用。我們可以通過(guò)設(shè)置this.$options._linkerCachable = false
達(dá)到我們的目的。
這樣我們就可以開(kāi)發(fā)讓用戶自定義布局的組件了,用戶傳入布局參數(shù),通過(guò)手工拼接模板,設(shè)置了_linkerCachable = false
也不會(huì)被緩存。
通過(guò) $options.partials 動(dòng)態(tài)添加 partial
使用 partials 也能達(dá)到添加自定義模板的目的,但是通常的做法是要全局注冊(cè) partial,這么做并不優(yōu)雅。 vue-strap 就是這么做的。如果重名了會(huì)被覆蓋(初次渲染不會(huì),但是數(shù)據(jù)更新重新渲染 DOM 時(shí)就會(huì)被覆蓋)。
通過(guò)文檔我們知道可以在組件內(nèi)部通過(guò) partials 屬性注冊(cè)局部的 partial,因此自然而然也可以在 this.$options.partials 去動(dòng)態(tài)添加了。
Vue.component('XSelect', { template: ``, props: ['template','value','options'], partials: { option: '' }, created() { if(this.template) { this.$options.partials.option =this.template } } })
用 interpolate 渲染模板
這種方式就略顯蛋疼,而且效率最差。 interpolate 也是我最開(kāi)始做動(dòng)態(tài)渲染模板想到的方式,不推薦使用。
Vue.component('XSelect', { template: ``, props: [ 'value', 'options', { name: 'template', default:'' } ], methods: { renderOption(option) { this.option = option returnthis.$interpolate(this.template) } } })
Vue2.0
目前并沒(méi)有找到合適的解決方案。2.0 的 Vue 將 compile 工作提前,并且 compiler 也是單獨(dú)一個(gè)包(除非你直接引用的是 vue.js 文件,包含 compiler 和 runtime,那么第一種方法是適用的),那么并不能動(dòng)態(tài)的生成模板。除非用戶傳入的是 render 能識(shí)別的 DOM tree。
按照這樣的思路,其實(shí)可以讓用戶傳入的模板預(yù)先編譯好,傳入到組件內(nèi),拼接 DOM tree 看起來(lái)也能解決問(wèn)題。那么可以這么玩。
看看就好, 性能太渣
首先要安裝 Vue JSX 的 相關(guān)插件
組件
Vue.component({ name: 'XSelect', render(h) { // 這里獲得的 this.template 其實(shí)是一個(gè)函數(shù),調(diào)用該函數(shù)返回 DOM // 因此這里的關(guān)鍵代碼是拼接一個(gè)新的函數(shù),接受 `option` 參數(shù)以及上下文 // 使用 new Function 創(chuàng)建一個(gè)新函數(shù) return({ this.options.map(option => this.$emit('input', option.value) } class="option"> { new Function('option', 'return ' + this.template)(option)(h) }) }
入口文件
newVue({ el: '#app', data () { return{ value: '' } }, created() { // 初始化需要傳入的模板,這里會(huì)被 Vue 的 JSX 插件轉(zhuǎn)成 DOM tree this.template = h =>標(biāo)簽: { option.label }, 值: { option.value } }, render(h) { return() } })
綜上,在 Vue 1.x 里不存在預(yù)編譯
的概念,所以想動(dòng)態(tài)修改模板還是有許多方式的,甚至還可以結(jié)合
取到slot
里的內(nèi)容拼接進(jìn)模板里。但 2.0 就麻煩了,并找不到理想的方法。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)建站的支持。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、建站服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。