摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的
說明
有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見,可以直接用 ng-include 搞定,在 Vue 1.x 的時(shí)候也可以直接用 partial 搞定。
但是在 Vue 2.x 中,官方取消了 partial 這個(gè) API,根據(jù)情況推薦使用 component 代替,參見這里
那我現(xiàn)在有個(gè)需求,就是從后臺(tái)獲取一個(gè)字符串模板(假設(shè)里面包含 v-model 等 vue 指令),模板需要拿到前臺(tái)來編譯,那該怎么實(shí)現(xiàn)呢?
(這種需求確實(shí)比較少見,但是是存在的。。。)
官方根據(jù)情況推薦了三種替代 partial 的方式,分別為:
normal component 常規(guī)組件,沒有處于性能關(guān)鍵區(qū)域(簡(jiǎn)單來說就是對(duì)性能有較大影響)時(shí)使用
dynamic component 動(dòng)態(tài)組件,根據(jù)組件名稱動(dòng)態(tài)綁定時(shí)使用
functional component 函數(shù)組件,處于性能關(guān)鍵區(qū)域時(shí)使用
另外根據(jù)文檔中的的情況來看:
異步組件和高級(jí)異步組件(異步組件) 也可能解決樓主的問題
下面來分別分析一下:
常規(guī)組件用法
// 注冊(cè) Vue.component("my-component", { template: "A custom component!" }) // 創(chuàng)建根實(shí)例 new Vue({ el: "#example" })
這是常規(guī)組件的注冊(cè)方法
先來看下 Vue 實(shí)例的聲明周期圖,摘自官網(wǎng):
圖中黃色的部分,可以看出 vue 實(shí)例的模板是來自哪里的?
el 選項(xiàng)提供的選擇器
template 選項(xiàng)提供的字符串 (當(dāng)然沒有的話會(huì)編譯組件的 outerHTML)
還有其他可能嗎?沒有了。。。而且兩個(gè)選項(xiàng)的提供都是在 beforeMount 之前,這說明啥?這說明這兩個(gè)選項(xiàng)一旦提供就不能改了!所以在聲明組件的時(shí)候就必須提供這兩個(gè)選項(xiàng)來作為編譯的模板,而且是不能更改的,那我如果想要異步拿到模板去編譯顯然不可能。
so,常規(guī)組件,卒。
動(dòng)態(tài)組件簡(jiǎn)單來說是使用
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 } })
從目前了解的情況來看,import 進(jìn)來的組件一般也都是準(zhǔn)備好的,如果想要異步加載可能需要 webpack 的一些功能,暫且先跳過。
那動(dòng)態(tài)組件可以是選項(xiàng)對(duì)象?那選項(xiàng)對(duì)象如果是異步的呢?好吧有希望~ 糖糖先記著~
這個(gè),看了第一遍文檔,不是太懂,沒關(guān)系!找關(guān)鍵的地方: API:render 函數(shù)
Vue 選項(xiàng)中的 render 函數(shù)若存在,則 Vue 構(gòu)造函數(shù)不會(huì)從 template 選項(xiàng)或通過 el 選項(xiàng)指定的掛載元素中提取出的 HTML 模板編譯 render 函數(shù)。
這里所說的很清楚,template 或 el 選項(xiàng)最終都會(huì)被編譯成 render 函數(shù),那如果有 render 函數(shù)的話,就會(huì)忽略那兩個(gè)選項(xiàng)。還是要看上面那張圖,render 函數(shù)是在 beforeMount 的時(shí)候就已經(jīng)編譯完成的,所以也是不能改變的。
so,函數(shù)組件,卒。
這里直接摘官網(wǎng)說明:
在大型應(yīng)用中,我們可能需要將應(yīng)用拆分為多個(gè)小模塊,按需從服務(wù)器下載。為了讓事情更簡(jiǎn)單,Vue.js 允許將組件定義為一個(gè)工廠函數(shù),動(dòng)態(tài)地解析組件的定義。Vue.js 只在組件需要渲染時(shí)觸發(fā)工廠函數(shù),并且把結(jié)果緩存起來,用于后面的再次渲染。例如:
Vue.component("async-example", function (resolve, reject) { setTimeout(function () { // Pass the component definition to the resolve callback resolve({ template: "I am async!" }) }, 1000) })
可以看出來,異步組件基本可以實(shí)現(xiàn)樓主的需求,但是上面是 ES5 的寫法,可以猜一下 ES6 的寫法可能如下:
// 某個(gè)vue文件 export default function (resolve, reject) { // 遠(yuǎn)程加載你的模板 apiService.then(data => { resolve({ template: data }) } }
但是這個(gè)樓主沒有實(shí)際用過,官方寫的 ES5 可以把選項(xiàng)對(duì)象定義成一個(gè)工廠方函數(shù),ES6 應(yīng)該可以直接返回工廠函數(shù)。感興趣的同學(xué)可以試一下然后告訴樓主。
樓主的方法樓主沒有用上面的異步組件(其實(shí)因?yàn)楫?dāng)時(shí)看不懂 囧),我在工作中使用的其實(shí)是 動(dòng)態(tài)組件結(jié)合 Vue 的 computed 屬性。靈感來源與 vue 論壇:innerhtml-compilation-vue
LinuxBorg 大神在論壇上回答另一個(gè)同學(xué)的提問時(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ì)說了。
小結(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://specialneedsforspecialkids.com/yun/51182.html
摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的 說明 有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見,可以直接用 ng-include...
摘要:前言這里筑夢(mèng)師是一名正在努力學(xué)習(xí)的開發(fā)工程師目前致力于全棧方向的學(xué)習(xí)希望可以和大家一起交流技術(shù)共同進(jìn)步用簡(jiǎn)書記錄下自己的學(xué)習(xí)歷程個(gè)人學(xué)習(xí)方法分享本文目錄更新說明目錄學(xué)習(xí)方法學(xué)習(xí)態(tài)度全棧開發(fā)學(xué)習(xí)路線很長(zhǎng)知識(shí)拓展很長(zhǎng)在這里收取很多人的建議以后決 前言 這里筑夢(mèng)師,是一名正在努力學(xué)習(xí)的iOS開發(fā)工程師,目前致力于全棧方向的學(xué)習(xí),希望可以和大家一起交流技術(shù),共同進(jìn)步,用簡(jiǎn)書記錄下自己的學(xué)習(xí)歷程...
摘要:前言這里筑夢(mèng)師是一名正在努力學(xué)習(xí)的開發(fā)工程師目前致力于全棧方向的學(xué)習(xí)希望可以和大家一起交流技術(shù)共同進(jìn)步用簡(jiǎn)書記錄下自己的學(xué)習(xí)歷程個(gè)人學(xué)習(xí)方法分享本文目錄更新說明目錄學(xué)習(xí)方法學(xué)習(xí)態(tài)度全棧開發(fā)學(xué)習(xí)路線很長(zhǎng)知識(shí)拓展很長(zhǎng)在這里收取很多人的建議以后決 前言 這里筑夢(mèng)師,是一名正在努力學(xué)習(xí)的iOS開發(fā)工程師,目前致力于全棧方向的學(xué)習(xí),希望可以和大家一起交流技術(shù),共同進(jìn)步,用簡(jiǎn)書記錄下自己的學(xué)習(xí)歷程...
閱讀 3807·2021-11-24 09:39
閱讀 1819·2021-11-02 14:41
閱讀 817·2019-08-30 15:53
閱讀 3485·2019-08-29 12:43
閱讀 1195·2019-08-29 12:31
閱讀 3091·2019-08-26 13:50
閱讀 801·2019-08-26 13:45
閱讀 993·2019-08-26 10:56