Vue-動態組件&異步導入

動態組件&異步導入

動態組件搭配異步導入做爲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

  • require模式

webpack遺留功能require.ensurees6

Vue.component('async-webpack-example', function (resolve) {
  // 這個特殊的 `require` 語法將會告訴 webpack
  // 自動將你的構建代碼切割成多個包,這些包
  // 會經過 Ajax 請求加載
  require(['./my-async-component'], resolve)
})
複製代碼
  • import模式-推薦使用

在工廠函數中返回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函數做爲變量直接被執行導入過程,避免導入的函數再次調用。

參考資料

Vue-動態組件&異步組件
webpack-動態導入
es6-import()

相關文章
相關標籤/搜索