當打包構建應用時,Javascript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。
結合 Vue 的 異步組件 和 Webpack 的 code splitting feature, 輕松實現路由組件的懶加載。
我們要做的就是把路由對應的組件定義成異步組件
const Foo = resolve => { // require.ensure 是 Webpack 的特殊語法,用來設置 code-split point // (代碼分塊) require.ensure(['./Foo.vue'], () => { resolve(require('./Foo.vue')) }) }
這里還有另一種代碼分塊的語法,使用 AMD 風格的 require,於是就更簡單了:
const Foo = resolve => require(['./Foo.vue'], resolve)
不需要改變任何路由配置,跟之前一樣使用 Foo
:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })
把組件按組分塊
有時候我們想把某個路由下的所有組件都打包在同個異步 chunk 中。只需要 給 chunk 命名,提供 require.ensure
第三個參數作為 chunk 的名稱:
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo') const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo') const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
Webpack 將相同 chunk 下的所有異步模塊打包到一個異步塊里面 —— 這也意味着我們無須明確列出 require.ensure
的依賴(傳空數組就行)。
如果你想在組件加載的時候可以有loading提示也同樣的很簡單
這里以mint-ui為例
import { Indicator } from 'mint-ui'; //前提是npm i mint-ui -S
然后你就只需要稍微加一點代碼
const Foo = resolve => { Indicator.open(); require.ensure(['./Foo.vue'], () => { resolve(require('./Foo.vue')) Indicator.close() }) } //這樣就可以實現組件在異步加載的時候顯示loading
效果如下