動態組件搭配異步導入做爲webpack編譯組件的基礎,提升代碼可讀性的同時使項目更加輕量且簡潔。javascript
本文介紹在Vue項目開發中,動態組件、異步導入過程及實踐html
動態組件渲染使用 is
attribute屬性 來切換不一樣的組件:vue
<component v-bind:is="currentTabComponent"></component>
複製代碼
每次切換新標籤。Vue都建立了一個新的currentTabComponent
實例。
從新建立動態組件的行爲儘管是很是有用的,可是某些標籤組件實例內部數據不會發生變化,若是但願可以在第一次被建立的時候被緩存下來,能夠用<keep-alive>
元素將其動態組件包裹起來。java
<!-- 失活的組件將會被緩存!-->
<keep-alive>
<component v-bind:is="currentTabComponent" ></component>
</keep-alive>
複製代碼
在大型應用開發中,組件的數量多且龐雜,此時組件的按需加載顯得重要且必要。
Vue容許以一個工廠函數的方式定義組件,工廠函數會異步解析組件的定義。
Vue只有在這個組件須要被渲染的時候纔會觸發該工廠函數,且會把結果緩存起來供將來渲染使用。webpack
webpack遺留功能require.ensurees6
Vue.component('async-webpack-example', function (resolve) {
// 這個特殊的 `require` 語法將會告訴 webpack
// 自動將你的構建代碼切割成多個包,這些包
// 會經過 Ajax 請求加載
require(['./my-async-component'], resolve)
})
複製代碼
在工廠函數中返回Promise
,利用es2015+webpack2動態導入:web
Vue.component(
'async-webpack-example',
// 這個動態導入會返回一個 `Promise` 對象。
() => import('./my-async-component')
)
複製代碼
當使用局部註冊時,直接返回Promise
函數:json
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
複製代碼
講解實際項目案例、分析過程及要點api
項目工做流審批詳情根據業務要求,須要展現每一個模塊獨立的審批詳情數據。數組
JSON
的數組代碼實踐分三個部分組件數據、頁面渲染、異步導入
JSON
的組件數據在大型應用中,能夠用在線excel收集組件信息,組件路徑能夠直接粘貼組件的相對路徑,再用腳本處理成標準的可直接使用的JSON
數組作半自動化處理。
[
{
"id": 111,//組件編號
"urlPath": "src/components/Card.vue",//組件相對路徑
"tag": "Card",//組件名稱
"extra":{}//冗餘參數
},
{
"id": 112,
"urlPath": "src/components/Message.vue",
"tag": "Message",
"extra":{}
}
]
複製代碼
公共詳情頁面此刻做爲一個殼子,各自的模塊組件放在殼中,代碼示例:
<template>
<div class="hello"> <!--帶緩存的動態組件--> <keep-alive> <component v-bind:is="currentTabComponent" :extra="extra" @updateCom="updateComponent" class="tab"></component> </keep-alive> </div>
</template>
<script> import componentList from "../work/components.json"//導入組件數據 import components from "../work/dataFlow";//組件異步導入 export default { name: "HelloWorld", components,//當即執行的異步導入組件 data() { return { msg: "Welcome to Your Vue.js App", currentTabComponent: "Message",//當前渲染組件 extra:{} }; }, created() { //模擬異步請求返回數據 setTimeout({code,data} => { //to do let result= componentList.find(item=>item.id == +data.id) let extra = result.extra this.extra = Object.keys(extra).length>0?extra:data this.currentTabComponent = result.tag; }, 500); }, methods:{ updateComponent(){ //to do } } }; </script>
複製代碼
異步導入的組件總體在dataFlow.js中處理,示例代碼:
// dataFlow.js
import list from '../work/components.json'
var result = ( ()=> {
let component = {};
for (let i = 0; i < list.length; i++) {
let com, path;
com = list[i]
path = com['urlPath'].substring(4,com['urlPath'].length)
component[com.tag] = ()=>import(`@/${path}`)//注意要點
}
return component
})()//當即執行函數
export default result
複製代碼
一、import沒法導入變量字符串做爲路徑
導入失敗寫法:
let path = '@/components/Message.vue';
let com = ()=>import(path)
複製代碼
導入成功寫法:
let path = '@/components/Message.vue';
copyPath = path.substring(2,path.length)
let com = ()=>import(`@/path`)
複製代碼
webpack目前不支持徹底意義上的動態導入。
能夠經過字符串模板功能幫助webpack識別主要路徑,這樣編譯時會編譯src下的模塊,但組件的只有在被渲染時才加載,從而實現異步導入。
二、當即執行函數
異步組件的導入處理成當即執行函數,會在頁面調用時導入的components
函數做爲變量直接被執行導入過程,避免導入的函數再次調用。