摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的
說(shuō)明
有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見(jiàn),可以直接用 ng-include 搞定,在 Vue 1.x 的時(shí)候也可以直接用 partial 搞定。
但是在 Vue 2.x 中,官方取消了 partial 這個(gè) API,根據(jù)情況推薦使用 component 代替,參見(jiàn)這里
那我現(xiàn)在有個(gè)需求,就是從后臺(tái)獲取一個(gè)字符串模板(假設(shè)里面包含 v-model 等 vue 指令),模板需要拿到前臺(tái)來(lái)編譯,那該怎么實(shí)現(xiàn)呢?
(這種需求確實(shí)比較少見(jiàn),但是是存在的。。。)
官方根據(jù)情況推薦了三種替代 partial 的方式,分別為:
normal component 常規(guī)組件,沒(méi)有處于性能關(guān)鍵區(qū)域(簡(jiǎn)單來(lái)說(shuō)就是對(duì)性能有較大影響)時(shí)使用
dynamic component 動(dòng)態(tài)組件,根據(jù)組件名稱(chēng)動(dòng)態(tài)綁定時(shí)使用
functional component 函數(shù)組件,處于性能關(guān)鍵區(qū)域時(shí)使用
另外根據(jù)文檔中的的情況來(lái)看:
異步組件和高級(jí)異步組件(異步組件) 也可能解決樓主的問(wèn)題
下面來(lái)分別分析一下:
常規(guī)組件用法
// 注冊(cè) Vue.component("my-component", { template: "A custom component!" }) // 創(chuàng)建根實(shí)例 new Vue({ el: "#example" })
這是常規(guī)組件的注冊(cè)方法
先來(lái)看下 Vue 實(shí)例的聲明周期圖,摘自官網(wǎng):
圖中黃色的部分,可以看出 vue 實(shí)例的模板是來(lái)自哪里的?
el 選項(xiàng)提供的選擇器
template 選項(xiàng)提供的字符串 (當(dāng)然沒(méi)有的話會(huì)編譯組件的 outerHTML)
還有其他可能嗎?沒(méi)有了。。。而且兩個(gè)選項(xiàng)的提供都是在 beforeMount 之前,這說(shuō)明啥?這說(shuō)明這兩個(gè)選項(xiàng)一旦提供就不能改了!所以在聲明組件的時(shí)候就必須提供這兩個(gè)選項(xiàng)來(lái)作為編譯的模板,而且是不能更改的,那我如果想要異步拿到模板去編譯顯然不可能。
so,常規(guī)組件,卒。
動(dòng)態(tài)組件簡(jiǎn)單來(lái)說(shuō)是使用
var vm = new Vue({ el: "#example", data: { currentView: "home" }, components: { home: { /* ... */ }, posts: { /* ... */ }, archive: { /* ... */ } } })
也可以是選項(xiàng)對(duì)象?。?/p>
var Home = { template: "Welcome home!
" } var vm = new Vue({ el: "#example", data: { currentView: Home } })
從目前了解的情況來(lái)看,import 進(jìn)來(lái)的組件一般也都是準(zhǔn)備好的,如果想要異步加載可能需要 webpack 的一些功能,暫且先跳過(guò)。
那動(dòng)態(tài)組件可以是選項(xiàng)對(duì)象?那選項(xiàng)對(duì)象如果是異步的呢?好吧有希望~ 糖糖先記著~
這個(gè),看了第一遍文檔,不是太懂,沒(méi)關(guān)系!找關(guān)鍵的地方: API:render 函數(shù)
Vue 選項(xiàng)中的 render 函數(shù)若存在,則 Vue 構(gòu)造函數(shù)不會(huì)從 template 選項(xiàng)或通過(guò) el 選項(xiàng)指定的掛載元素中提取出的 HTML 模板編譯 render 函數(shù)。
這里所說(shuō)的很清楚,template 或 el 選項(xiàng)最終都會(huì)被編譯成 render 函數(shù),那如果有 render 函數(shù)的話,就會(huì)忽略那兩個(gè)選項(xiàng)。還是要看上面那張圖,render 函數(shù)是在 beforeMount 的時(shí)候就已經(jīng)編譯完成的,所以也是不能改變的。
so,函數(shù)組件,卒。
這里直接摘官網(wǎng)說(shuō)明:
在大型應(yīng)用中,我們可能需要將應(yīng)用拆分為多個(gè)小模塊,按需從服務(wù)器下載。為了讓事情更簡(jiǎn)單,Vue.js 允許將組件定義為一個(gè)工廠函數(shù),動(dòng)態(tài)地解析組件的定義。Vue.js 只在組件需要渲染時(shí)觸發(fā)工廠函數(shù),并且把結(jié)果緩存起來(lái),用于后面的再次渲染。例如:
Vue.component("async-example", function (resolve, reject) { setTimeout(function () { // Pass the component definition to the resolve callback resolve({ template: "I am async!" }) }, 1000) })
可以看出來(lái),異步組件基本可以實(shí)現(xiàn)樓主的需求,但是上面是 ES5 的寫(xiě)法,可以猜一下 ES6 的寫(xiě)法可能如下:
// 某個(gè)vue文件 export default function (resolve, reject) { // 遠(yuǎn)程加載你的模板 apiService.then(data => { resolve({ template: data }) } }
但是這個(gè)樓主沒(méi)有實(shí)際用過(guò),官方寫(xiě)的 ES5 可以把選項(xiàng)對(duì)象定義成一個(gè)工廠方函數(shù),ES6 應(yīng)該可以直接返回工廠函數(shù)。感興趣的同學(xué)可以試一下然后告訴樓主。
樓主的方法樓主沒(méi)有用上面的異步組件(其實(shí)因?yàn)楫?dāng)時(shí)看不懂 囧),我在工作中使用的其實(shí)是 動(dòng)態(tài)組件結(jié)合 Vue 的 computed 屬性。靈感來(lái)源與 vue 論壇:innerhtml-compilation-vue
LinuxBorg 大神在論壇上回答另一個(gè)同學(xué)的提問(wèn)時(shí)提到的,可以看到下面還有樓主的留言~
computed: { dynComponent() { const template = this.content ? this.content : "nothing here yet" return { template, // use content as template for this component props: this.$options.props // re-use current props definitions } }
即 computed 屬性直接返回一個(gè)組件的選項(xiàng)對(duì)象,這個(gè)選項(xiàng)對(duì)象的模板可以異步獲取,然后配合 動(dòng)態(tài)組件
當(dāng)然樓主用的比這個(gè)復(fù)雜一些,會(huì)涉及到 v-model 等雙向綁定,需要將這個(gè)組件再封裝一層并且轉(zhuǎn)換一下模板,這里就不細(xì)說(shuō)了。
小結(jié)總之呢,上面分析了在 VueJS 2.x 中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法:
異步組件,應(yīng)該是官方的推薦方法
動(dòng)態(tài)組件 + computed,變通之法,論壇上發(fā)現(xiàn)的思路
當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出~
本文發(fā)自我的blog,原文鏈接: 我的blog
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85002.html
摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的 說(shuō)明 有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見(jiàn),可以直接用 ng-include...
摘要:前言這里筑夢(mèng)師是一名正在努力學(xué)習(xí)的開(kāi)發(fā)工程師目前致力于全棧方向的學(xué)習(xí)希望可以和大家一起交流技術(shù)共同進(jìn)步用簡(jiǎn)書(shū)記錄下自己的學(xué)習(xí)歷程個(gè)人學(xué)習(xí)方法分享本文目錄更新說(shuō)明目錄學(xué)習(xí)方法學(xué)習(xí)態(tài)度全棧開(kāi)發(fā)學(xué)習(xí)路線很長(zhǎng)知識(shí)拓展很長(zhǎng)在這里收取很多人的建議以后決 前言 這里筑夢(mèng)師,是一名正在努力學(xué)習(xí)的iOS開(kāi)發(fā)工程師,目前致力于全棧方向的學(xué)習(xí),希望可以和大家一起交流技術(shù),共同進(jìn)步,用簡(jiǎn)書(shū)記錄下自己的學(xué)習(xí)歷程...
摘要:前言這里筑夢(mèng)師是一名正在努力學(xué)習(xí)的開(kāi)發(fā)工程師目前致力于全棧方向的學(xué)習(xí)希望可以和大家一起交流技術(shù)共同進(jìn)步用簡(jiǎn)書(shū)記錄下自己的學(xué)習(xí)歷程個(gè)人學(xué)習(xí)方法分享本文目錄更新說(shuō)明目錄學(xué)習(xí)方法學(xué)習(xí)態(tài)度全棧開(kāi)發(fā)學(xué)習(xí)路線很長(zhǎng)知識(shí)拓展很長(zhǎng)在這里收取很多人的建議以后決 前言 這里筑夢(mèng)師,是一名正在努力學(xué)習(xí)的iOS開(kāi)發(fā)工程師,目前致力于全棧方向的學(xué)習(xí),希望可以和大家一起交流技術(shù),共同進(jìn)步,用簡(jiǎn)書(shū)記錄下自己的學(xué)習(xí)歷程...
閱讀 3558·2021-11-08 13:15
閱讀 2115·2019-08-30 14:20
閱讀 1398·2019-08-28 18:08
閱讀 990·2019-08-28 17:51
閱讀 1499·2019-08-26 18:26
閱讀 3003·2019-08-26 13:56
閱讀 1499·2019-08-26 11:46
閱讀 2595·2019-08-23 14:22