Vue路由懶加載


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僅是用來演示異步傳遞組件定義用。將異步組件和webpackcode-splitting功能一起配合使用可以達到懶加載組件的效果。

Vue.component("async-webpack-example", function (resolve) {
  // 這個特殊的 `require` 語法將會告訴 webpack
  // 自動將你的構建代碼切割成多個包,這些包
  // 會通過 Ajax 請求加載
  require(["./my-async-component"], resolve)
})

也可以在工廠函數中返回一個Promise,把webpack 2ES2015語法加在一起。

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

使用webpackrequire.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM