vue 懒加载实践

Posted HelloHello233

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 懒加载实践相关的知识,希望对你有一定的参考价值。

参考:

  https://router.vuejs.org/zh-cn/advanced/lazy-loading.html

路由懒加载

// 配置文件
module.exports = {
    entry: {
        index: \'./index.js\',
    },
    output: {
        path: __dirname + "/dist",
        filename: "[name].js",
        publicPath:"./dist/"
    },
    devtool: \'eval-source-map\',
    module: {
        rules: [
            {
                test: /\\.vue$/,
                loader: \'vue-loader\'
            },
            {
                test: /(\\.jsx|\\.js)$/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["es2015"],
                        plugins: ["syntax-dynamic-import"]
                    }
                },
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [".vue",".js",".json"],
        alias: {
            \'vue$\': \'vue/dist/vue.js\',
        }
    }
};

// ./routers/uA.vue
<template>
    <div>
        aaaaaaaaaaa
    </div>
</template>

<script>
    export default {
        name: "v-a"
    }
</script>
<style scoped></style>

// ./routers/uB.vue
<template>
    <div>
        bbbbbbbbbbb
    </div>
</template>

<script>
    export default {
        name: "v-b"
    }
</script>
<style scoped></style>

// index.js
import VueRouter from "vue-router"
import Vue from "vue"

const vA = ()=> import(\'./routers/vA\')
const vB = ()=> import(\'./routers/vB\')

const router = new VueRouter({
    routes: [
        { path: \'/a\', component: vA },
        { path: \'/b\', component: vB }
    ]
})
Vue.use(VueRouter)
new Vue({
    el:"#root",
    router:router
});

// main.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="root">
        <router-link to="/a">Go to a</router-link>
        <router-link to="/b">Go to b</router-link>
        <router-view></router-view>
    </div>
</body>
<script src="dist/index.js"></script>
</html>

// 依赖
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-preset-es2015": "^6.24.1",
    "css-loader": "^0.28.8",
    "style-loader": "^0.19.1",
    "vue": "^2.5.13",
    "vue-loader": "^13.6.2",
    "vue-router": "^3.0.1",
    "vue-template-compiler": "^2.5.13",
    "webpack": "^3.10.0"
  }
View Code

 仅当这个路由组件第一次需要被显示的时候,才会下载这个组件。打包后dist出现这几个文件:

0和1代表被异步加载的路由组件。 

如果手误,import一个vue-loader,则会报如下错误:

WARNING in ./node_modules/vue-loader/lib/utils/try-require.js
12:11-27 Critical dependency: the request of a dependency is an expression
@ ./node_modules/vue-loader/lib/utils/try-require.js
@ ./node_modules/vue-loader/lib/loader.js
@ ./node_modules/vue-loader/index.js
@ ./index.js

 

ERROR in ./node_modules/resolve/lib/async.js
Module not found: Error: Can\'t resolve \'fs\' in \'C:\\Users\\MRLWJ\\Desktop\\test\\router\\node_modules\\resolve\\lib\'
@ ./node_modules/resolve/lib/async.js 2:9-22
@ ./node_modules/resolve/index.js
@ ./node_modules/vue-loader/lib/utils/try-require.js
@ ./node_modules/vue-loader/lib/loader.js
@ ./node_modules/vue-loader/index.js
@ ./index.js

Api

关于路由守卫:https://router.vuejs.org/zh-cn/advanced/navigation-guards.html

this.$router.push(\'/qwe\'):

  修改路由为 #/qwe(路由组件会切换),不发出请求

router.onReady

  回调函数被调用的时候,就意味着当前要显示的(同步或者异步)路由组件已经准备好了,这时这个路由组件还没有完成挂载(onReady的回调函数在组件beforeCreate前执行)。

router.beforeEach

  在路由切换前执行(页面打开时也会执行一次),回调函数中需要调用next(),否则路由不切换。可以注册多个,会按次序执行,上一个没有执行next的话,下一个不会执行,路由不会切换,当最后一个执行了next时,路由才开始切换(组件开始挂载)

文档中提示的触发流程如下:

  1. Navigation triggered.
  2. Call leave guards in deactivated components.
  3. Call global beforeEach guards.
  4. Call beforeRouteUpdate guards in reused components (2.2+).
  5. Call beforeEnter in route configs.
  6. Resolve async route components.
  7. Call beforeRouteEnter in activated components.
  8. Call global beforeResolve guards (2.5+).
  9. Navigation confirmed.
  10. Call global afterEach hooks.
  11. DOM updates triggered.
  12. Call callbacks passed to next in beforeRouteEnter guards with instantiated instances.

以上流程中,只要next没执行,就不会到下一步,如进行以下设置:

beforeRouteEnter(to,form,next){
    setTimeout(()=>{
        next()
    },2000)
}    

 则全局的beforeResolve会等待以上的next执行后执行。

切换路由,组件由A->B时:

 

在路由中,component reused 的意思是路由没有发生变化,而仅仅参数发生了变化(user/1 -> user/2),这时组件中的钩子 beforeRouteUpdate会执行。

 

以上是关于vue 懒加载实践的主要内容,如果未能解决你的问题,请参考以下文章

VUE的路由懒加载及组件懒加载

vue路由懒加载及组件懒加载

Vue路由懒加载与组件懒加载

React自定义组件之懒加载-LazyLoad。

java 的ViewPage +片段懒加载

Vue教程(四十二)路由懒加载