中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue如何動態添加模板

發布時間:2022-10-31 10:32:02 來源:億速云 閱讀:142 作者:iii 欄目:開發技術

今天小編給大家分享一下Vue如何動態添加模板的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

例如要做一個類 select 的組件,用戶傳入 options 數據,通過 value prop 獲取選中值,最基本的原型如下。

Vue.component('XSelect', {
 template: `
 <div class="select">
 <input :value="value" readonly />
 <div
 class="option"
 v-for="option in options"
 @click="value = option.value">
 <span v-text="option.label"></span>
 </div>
 </div>`,

 props: ['value','options']
})

如果此時需要增加一個 API 支持讓用戶自定義 option 部分的模板。此處用 slot 并不能解決問題。

通過 $options.template 修改

通過打印組件對象可以獲得一個信息,在 $options 里定義了一個 template 屬性,寫在 template 標簽里的模板,最終編譯后也會在 $options.template 里。通過文檔的生命周期 可以得知,在 created 的時候, 實例已經結束解析選項, 但是還沒有開始 DOM 編譯 也就是說,如果用戶通過 prop 的數據我們可以獲得,但是模板其實還沒有渲染成 DOM。經過測試,在 created 修改 this.$options.template 是可以改變最終生成的 DOM 的,同時也能拿到 props 的內容。

那么我們可以修改下代碼,使其支持自定義模板

Vue.component('XSelect', {
 props: [
'value',
'options',
 {
 name: 'template',
default:'<span v-text="option.label"></span>'
 }
 ],

 created() {
varoptionTpl =this.template

this.$options.template =`
 <div class="select">
 <input :value="value" readonly />
 <div
 class="option"
 v-for="option in options"
 @click="value = option.value">
${optionTpl}
 </div>
 </div>`
 }
})

用戶使用是就可以傳入模板了

<x-select
:value.sync="value"
template="<span>標簽: {{ option.label }}, 值: {{ option.value }}</span>"
:options="[
 {value: 1, label: 'a'},
 {value: 2, label: 'b'},
 {value: 3, label: 'c'}
 ]">
</x-select>

可能存在的問題

我們知道 Vue 在內部幫我們做了許多優化,但是在這里可能會由于某些優化導致動態拼接的模板無法渲染成功。例如這里我們不使用 v-for 而是手工遍歷 options 生成需要的 HTML

consttpl = options.map(opt =>`<div>${this.optionTpl}</div>`)

this.$options.template =`
 <div class="select">
 <input :value="value" readonly>
${tpl}
 </div>`

這里會導致一個 BUG,如果一個頁面有多個 x-select 組件,并且 options 長度不一樣,會導致長的 options 的組件后面幾個選項渲染不出來。究其原因是 Vue 會幫我們緩存模板編譯結果。翻看代碼可以找到 vue/src/instance/internal/lifecycle.js 里有做優化,同時提供的 _linkerCachable 本意是給 內聯模板 使用。我們可以通過設置 this.$options._linkerCachable = false 達到我們的目的。

這樣我們就可以開發讓用戶自定義布局的組件了,用戶傳入布局參數,通過手工拼接模板,設置了 _linkerCachable = false 也不會被緩存。

通過 $options.partials 動態添加 partial

使用 partials 也能達到添加自定義模板的目的,但是通常的做法是要全局注冊 partial,這么做并不優雅。 vue-strap 就是這么做的。如果重名了會被覆蓋(初次渲染不會,但是數據更新重新渲染 DOM 時就會被覆蓋)。

通過文檔我們知道可以在組件內部通過 partials 屬性注冊局部的 partial,因此自然而然也可以在 this.$options.partials 去動態添加了。

Vue.component('XSelect', {
 template: `
 <div class="select">
 <input :value="value" readonly />
 <div
 class="option"
 v-for="option in options"
 @click="value = option.value">
 <partial name="option"></partial>
 </div>
 </div>`,

 props: ['template','value','options'],

 partials: {
 option: '<span v-text="option.label"></span>'
 },

 created() {
if(this.template) {
this.$options.partials.option =this.template
 }
 }
})

用 interpolate 渲染模板

這種方式就略顯蛋疼,而且效率最差。 interpolate 也是我最開始做動態渲染模板想到的方式,不推薦使用。

Vue.component('XSelect', {
 template: `
 <div class="select">
 <input :value="value" readonly />
 <div
 class="option"
 v-for="option in options"
 @click="value = option.value"
 v-html="renderOption(option)">
 </div>
 </div>`,

 props: [
'value',
'options',
 {
 name: 'template',
default:'<span v-text="option.label"></span>'
 }
 ],

 methods: {
 renderOption(option) {
this.option = option
returnthis.$interpolate(this.template)
 }
 }
})

Vue2.0

目前并沒有找到合適的解決方案。2.0 的 Vue 將 compile 工作提前,并且 compiler 也是單獨一個包(除非你直接引用的是 vue.js 文件,包含 compiler 和 runtime,那么第一種方法是適用的),那么并不能動態的生成模板。除非用戶傳入的是 render 能識別的 DOM tree。

按照這樣的思路,其實可以讓用戶傳入的模板預先編譯好,傳入到組件內,拼接 DOM tree 看起來也能解決問題。那么可以這么玩。

看看就好, 性能太渣

首先要安裝 Vue JSX 的 相關插件

組件

Vue.component({
 name: 'XSelect',

 render(h) {
// 這里獲得的 this.template 其實是一個函數,調用該函數返回 DOM
// 因此這里的關鍵代碼是拼接一個新的函數,接受 `option` 參數以及上下文
// 使用 new Function 創建一個新函數

return(
<divclass="select">
<inputvalue={this.value}readonly/>
 {
 this.options.map(option =>
<div
on-click={() => this.$emit('input', option.value) }
 class="option">
 { new Function('option', 'return ' + this.template)(option)(h) }
</div>
 )
 }
</div>)
 },

 props: ['template', 'value', 'options']
})

入口文件

newVue({
 el: '#app',

 data () {
return{
 value: ''
 }
 },

 created() {
// 初始化需要傳入的模板,這里會被 Vue 的 JSX 插件轉成 DOM tree
this.template = h =><span>標簽: { option.label }, 值: { option.value }</span>
 },

 render(h) {
return(
<x-select
v-model="value"
:template="template"
:options="[
 {value: 1, label: 'a'},
 {value: 2, label: 'b'},
 {value: 3, label: 'c'}
 ]">
</x-select>)
 }
})

Vue的優點

Vue具體輕量級框架、簡單易學、雙向數據綁定、組件化、數據和結構的分離、虛擬DOM、運行速度快等優勢,Vue中頁面使用的是局部刷新,不用每次跳轉頁面都要請求所有數據和dom,可以大大提升訪問速度和用戶體驗。

以上就是“Vue如何動態添加模板”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

阿拉善右旗| 宁夏| 塔城市| 黔西县| 佛学| 房产| 天长市| 青河县| 民县| 怀化市| 绥棱县| 潞城市| 琼海市| 霍林郭勒市| 紫阳县| 武鸣县| 新源县| 南皮县| 东阳市| 梁平县| 轮台县| 科技| 社会| 巴林左旗| 海伦市| 庆云县| 湘阴县| 临汾市| 锦州市| 平果县| 丰原市| 辉南县| 阳泉市| 晋宁县| 汕头市| 睢宁县| 闸北区| 通城县| 永州市| 南和县| 浦北县|