Vue路由懶加載
對於SPA
單頁應用,當打包構建時,JavaScript
包會變得非常大,影響頁面加載速度,將不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這就是路由的懶加載。
實現方式
Vue異步組件
Vue
允許以一個工廠函數的方式定義你的組件,這個工廠函數會異步解析你的組件定義。Vue
只有在這個組件需要被渲染的時候才會觸發該工廠函數,且會把結果緩存起來供未來重渲染。
Vue.component("async-example", function (resolve, reject) {
setTimeout(function() {
// 向 `resolve` 回調傳遞組件定義
resolve({
template: "<div>I am async!</div>"
})
}, 1000)
})
這個工廠函數會收到一個resolve
回調,這個回調函數會在你從服務器得到組件定義的時候被調用,當然也可以調用reject(reason)
來表示加載失敗,此處的setTimeout
僅是用來演示異步傳遞組件定義用。將異步組件和webpack
的code-splitting
功能一起配合使用可以達到懶加載組件的效果。
Vue.component("async-webpack-example", function (resolve) {
// 這個特殊的 `require` 語法將會告訴 webpack
// 自動將你的構建代碼切割成多個包,這些包
// 會通過 Ajax 請求加載
require(["./my-async-component"], resolve)
})
也可以在工廠函數中返回一個Promise
,把webpack 2
和ES2015
語法加在一起。
Vue.component(
"async-webpack-example",
// 這個動態導入會返回一個 `Promise` 對象。
() => import("./my-async-component")
)
事實上我們在Vue-Router
的配置上可以直接結合Vue
的異步組件和Webpack
的代碼分割功能可以實現路由組件的懶加載,打包后每一個組件生成一個js
文件。
{
path: "/example",
name: "example",
//打包后,每個組件單獨生成一個chunk文件
component: reslove => require(["@/views/example.vue"], resolve)
}
動態import
在Webpack2
中,可以使用動態import
語法來定義代碼分塊點split point
,官方也是推薦使用這種方法,如果使用的是Bable
,需要添加syntax-dynamic-import
插件, 才能使Babel
可以正確的解析語法。
//默認將每個組件,單獨打包成一個js文件
const example = () => import("@/views/example.vue")
有時我們想把某個路由下的所有組件都打包在同一個異步塊chunk
中,需要使用命名chunk
一個特殊的注釋語法來提供chunk name
,需要webpack > 2.4
。
const example1 = () => import(/* webpackChunkName: "Example" */ "@/views/example1.vue");
const example2 = () => import(/* webpackChunkName: "Example" */ "@/views/example2.vue");
事實上我們在Vue-Router
的配置上可以直接定義懶加載。
{
path: "/example",
name: "example",
//打包后,每個組件單獨生成一個chunk文件
component: () => import("@/views/example.vue")
}
webpack提供的require.ensure
使用webpack
的require.ensure
,也可以實現按需加載,同樣多個路由指定相同的chunkName
也會合並打包成一個js
文件。
// require.ensure(dependencies: String[], callback: function(require), chunkName: String)
{
path: "/example1",
name: "example1",
component: resolve => require.ensure([], () => resolve(require("@/views/example1.vue")), "Example")
},
{
path: "/example2",
name: "example2",
component: resolve => require.ensure([], () => resolve(require("@/views/example2.vue")), "Example")
}
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://zhuanlan.zhihu.com/p/46843949
https://www.jianshu.com/p/c27b1640a01b
https://juejin.im/post/6844904025746309127
https://juejin.im/post/6844904013842874376
https://segmentfault.com/a/1190000011519350
https://cn.vuejs.org/v2/guide/components-dynamic-async.html
https://router.vuejs.org/zh/guide/advanced/lazy-loading.htm