vue2組件實現懶載入淺析,vue2組件淺析
一、 什麼是懶載入
懶載入也叫消極式載入,即在需要的時候進行載入,隨用隨載。
二、為什麼需要懶載入
在單頁應用中,如果沒有應用懶載入,運用webpack打包後的檔案將會異常的大,造成進入首頁時,需要載入的內容過多,延時過長,不利於使用者體驗,而運用懶載入則可以將頁面進行劃分,需要的時候載入頁面,可以有效分擔首頁所承擔的載入壓力,減少首頁載入用時
三、如何與webpack配合實現組件懶載入
1、在webpack設定檔中的output路徑配置chunkFilename屬性
output: { path: resolve(__dirname, 'dist'), filename: options.dev ? '[name].js' : '[name].js?[chunkhash]', chunkFilename: 'chunk[id].js?[chunkhash]', publicPath: options.dev ? '/assets/' : publicPath },
chunkFilename路徑將會作為組件懶載入的路徑
2、配合webpack支援的非同步載入方法
- resolve => require([URL], resolve), 支援性好
- () => system.import(URL) , webpack2官網上已經聲明將逐漸廢除, 不推薦使用
- () => import(URL), webpack2官網推薦使用, 屬於es7範疇, 需要配合babel的syntax-dynamic-import外掛程式使用, 具體使用方法如下
複製代碼 代碼如下:
npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-import babel-preset-es2015
use: [{ loader: 'babel-loader', options: { presets: [['es2015', {modules: false}]], plugins: ['syntax-dynamic-import'] } }]
四、具體執行個體中實現懶載入
1、路由中配置非同步裝置
export default new Router({ routes: [ { mode: 'history', path: '/my', name: 'my', component: resolve => require(['../page/my/my.vue'], resolve),//懶載入 }, ]})
2、執行個體中配置非同步裝置
components: { historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懶載入 //historyTab: () => import('../../component/historyTab/historyTab.vue') },
3、全域註冊非同步裝置
Vue.component('mideaHeader', () => { System.import('./component/header/header.vue')})
五、配置非同步裝置實現懶載入的問題分析
1、多次進出同一個非同步載入頁面是否會造成多次載入組件?
答:否,首次需要用到組件時瀏覽器會發送請求載入組件,載入完將會緩衝起來,以供之後再次用到該組件時調用
2、在多個地方使用同一個非同步裝置時是否造成多次載入組件?如:
//a頁面export default { components: { historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懶載入 },}//b頁面export default { components: { historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懶載入 },}
答:否,理由同上
3、如果在兩個非同步載入的頁面中分別同步與非同步載入同一個組件時是否會造成資源重用? 如:
//a頁面import historyTab from '../../component/historyTab/historyTab.vue';export default { components: { historyTab },}//b頁面export default { components: { historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懶載入 },}
答: 會, 將會造成資源重用, 根據打包後輸出的結果來看, a頁面中會嵌入historyTab組件的代碼, b頁面中的historyTab組件還是採用非同步載入的方式, 另外打包chunk;
解決方案: 組件開發時, 如果根頁面沒有匯入組件的情況下,而是在其他非同步載入頁面中同時用到組件, 那麼為實現資源的最大利用,在協同開發的時候全部人都使用非同步載入組件
4、在非同步載入頁面中載嵌入非同步載入的組件時對頁面是否會有渲染延時影響?
答:會, 非同步載入的組件將會比頁面中其他元素滯後出現, 頁面會有瞬間閃跳影響;
解決方案:因為在首次載入組件的時候會有載入時間, 出現頁面滯後, 所以需要合理的進行頁面結構設計, 避免首次出現跳閃現象;
六、懶載入的最終實現方案
1、路由頁面以及路由頁面中的組件全都使用懶載入
優點:(1)最大化的實現隨用隨載
(2)團隊開發不會因為溝通問題造成資源的重複浪費
缺點:(1)當一個頁面中嵌套多個組件時將發送多次的http請求,可能會造成網頁顯示過慢且渲染參差不齊的問題
2、路由頁面使用懶載入, 而路由頁面中的組件按需進行懶載入, 即如果組件不大且使用不太頻繁, 直接在路由頁面中匯入組件, 如果組件使用較為頻繁使用懶載入
優點:(1)能夠減少頁面中的http請求,頁面顯示效果好
缺點:(2)需要團隊事先交流, 在架構中分別建立懶載入組件與非懶載入組件檔案夾
3、路由頁面使用懶載入,在不特別影響首頁顯示延遲的情況下,根頁面合理匯入複用組件,再結合方案2
優點:(1)合理解決首頁延遲顯示問題
(2)能夠最大化的減少http請求, 且做其他他路由介面的顯示效果最佳
缺點:(1)還是需要團隊交流,建立合理區分各種載入方式的組件檔案夾
七、採用第三種方案進行目錄結構設計
八、具體代碼實現設計
1、路由設計:
import Router from 'vue-router';import Vue from 'vue';Vue.use(Router);export default new Router({ routes: [ { mode: 'history', path: '/home', name: 'home', component: resolve => require([URL], resolve),//懶載入 children: [ { mode: 'history', path: '/home/:name', name: 'any', component: resolve => require(['../page/any/any.vue'], resolve),//懶載入 }, ] }, { mode: 'history', path: '/store', name: 'store', component: resolve => require(['../page/store/store.vue'], resolve),//懶載入, children: [ { mode: 'history', path: '/store/:name', name: 'any', component: resolve => require(['../page/any/any.vue'], resolve),//懶載入 }, ] }, { mode: 'history', path: '/my', name: 'my', component: resolve => require(['../page/my/my.vue'], resolve),//懶載入, children: [ { mode: 'history', path: '/my/:name', name: 'any', component: resolve => require(['../page/any/any.vue'], resolve),//懶載入 }, ] }, ]})
(1)首層的路由根組件分別對應的tab頁面
(2)根目錄後跟著各個子路由頁面,子路由採用動態路由配合路由的編程式導航再加上vuex,最佳化提高開發效率
直接貼上代碼:
/** * Created by ZHANZF on 2017-3-20. *///vuex配置import Vue from 'vue';import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({ state: { //路由群組件儲存空間 routers: {} }, getters: { routers: state => { return state.data; } }, mutations: { //動態增加路由 addRouter: (state, data) => { state.routers = Object.assign({}, state.routers, { [data.name]: data.component }); } }, actions: { acMethods({commit}) { } },}) //根目錄中註冊路由群組件window.midea = { registerRouter(name, component) { Store.commit('addRouter', { name: name, component: component }) }};//頁面使用路由導航 openAnyPage() { midea.registerRouter('module', resolve => {require(['../module/module.vue'], resolve)});//懶載入 this.$router.push({path: '/home/module', query: {title: this.title}});}
//頁面中使用動態組件 <template> <component :is="currentRouter" :moduleName="title"></component> </template><script src="./any.js">export default { data () { return { routeName: '', currentRouter: '', title: '', } }, created() { this.routeName = this.$route.params.name; this.title = this.$route.query.title; this.currentRouter = this.$store.state.routers[this.routeName]; }, methods: { }}</script>
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。