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