zoukankan      html  css  js  c++  java
  • 第十四节:VueRouter4.x简介、基本用法、路由懒加载(打包分析)、动态路由、路由嵌套、相关Api

    一. 简介和基本用法

    1. 简介

     (官网地址:https://next.router.vuejs.org/zh/introduction.html)

     Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

    • 嵌套路由映射
    • 动态路由选择
    • 模块化、基于组件的路由配置
    • 路由参数、查询、通配符
    • 展示由 Vue.js 的过渡系统提供的过渡效果
    • 细致的导航控制
    • 自动激活 CSS 类的链接
    • HTML5 history 模式或 hash 模式
    • 可定制的滚动行为
    • URL 的正确编码

    PS:本章节使用的VueRouter版本为4.0.12

    2. 基本用法

    (1). 通过VueCli创建项目,并且选择包含VueRouter,会自动导入并生成VueRouter的相关配置文件

     A. 核心配置文件:src/router/index.js  (默认生成的文件如下,后面自己改造)

    import { createRouter, createWebHashHistory } from 'vue-router'
    import Home from '../views/Home.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    View Code

     B. main.js中需要以类似插件的形式导入vuerouter

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    
    createApp(App).use(router).mount('#app')

    (2). 在Views文件夹里创建两个组件页面 Home.vue 和 About.vue ,代码如下

    Home.vue

    <template>
        <div>
            我是Home组件
        </div>
    </template>
    
    <script>
        import { ref } from 'vue';
    
        export default {
            setup() {
    
            }
        }
    </script>
    
    <style scoped>
    </style>
    View Code

    About.vue 

    <template>
        <div>
            我是About组件
        </div>
    </template>
    
    <script>
        import { ref } from 'vue';
    
        export default {
            setup() {
    
            }
        }
    </script>
    
    <style scoped>
    </style>
    View Code

    (3). 配置路由映射

     A. Home组件配置成直接加载,About组件配置成懒加载,并且将About组件打包后生成的名字配置成 about 。

     B. 通过createRouter创建路由对象,并且传入routes和Hash模式 

     C. 配置路由默认路径/,自动跳转到Home组件

    代码分享:

    import { createRouter, createWebHashHistory } from 'vue-router'
    import Home from '../views/Home.vue'
    
    const routes = [
        // 默认路径自动跳转到Home组件
        {
            path: "/",
            redirect: "/home"
        },
        // 下面匹配规则
        {
            path: '/home',
            name: 'Home',
            component: Home
        },
        {
            path: '/about',
            name: 'About',
            component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
        }
    ]
    
    const router = createRouter({
        history: createWebHashHistory(),
        routes
    })
    
    export default router

    (4). 配置主页面

     在App.vue页面,利用<router-view />进行路由占位显示,利用</router-link>进行路由跳转操作。 

    PS:<router-view>的作用,用来占位显示 <router-link> 链接到的组件。

    App.vue代码如下: 

    <template>
        <div>
            <div class="nav">
                <router-link to="/home">Home</router-link> |
                <router-link to="/about">About</router-link>
            </div>
            <router-view />
        </div>
    </template>
    
    <script>
        import { ref } from 'vue';
    
        export default {
            setup() {
    
            }
        }
    </script>
    
    <style scoped>
        .nav{
            margin-bottom: 20px;
        }
    </style>
    View Code

    (5). 运行效果 

    补充几个知识点:

    1. 路由地址的模式

     有 hash模式 和 history模式,通过下面代码控制: createWebHashHistory是hash模式,createwebHistory是history模式

    import { createRouter, createWebHashHistory, createWebHistory } 
    const router = createRouter({
        history: createWebHistory(),
        routes
    })

     hash模式的地址形式:http://localhost:8080/#/home

     history模式的地址形式:http://localhost:8080/home

    2. <router-link>内质组件的属性

     (1). to属性:是一个字符串,或者是一个对象

     (2). replace属性:设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();

     (3). active-class属性:设置激活a元素后应用的class,默认是router-link-active;

     (4). exact-active-class属性:链接精准激活时,应用于渲染的 <a> 的 class,默认是router-link-exact-active;

    eg: 设置如下代码,选中后的标签效果:

    <style scoped>
        .router-link-active{
            color: green;
            font-weight: bold;
        }
    </style>

     

    二. 路由懒加载/打包分析

    1. 背景

     当打包构建应用时,JavaScript 包会变得非常大,影响页面加载:

     如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效;

    PS:默认运行【npm run build】打包,会生成两个js文件,app.xxxx.js  和 chunk-vendors.xxxx.js ,app.js存放的是自己写的代码,chunk-vendors.js存放的是第三方依赖的代码。 

    2. 实操

     这里可以用webpack的分包知识,Vue Router默认就支持动态来导入组件,从而提高首屏的渲染效率;

     用法:component可以传入一个组件,也可以接收一个函数,该函数 需要放回一个Promise;而import函数就是返回一个Promise;同时可以指定打包后生成的名字

    如下:把About组件通过懒加载的方式进行导入,并且指定打包后生成的名字为about

    const routes = [
        // 空路径自动跳转到Home组件
        {
            path: "/",
            redirect: "/home"
        },
        // 下面匹配规则
        {
            path: '/home',
            name: 'Home',
            component: Home
        },
        {
            path: '/about',
            name: 'About',
            component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
        }
    ]

    3. 打包分析

      通过【npm run build】进行打包,打包后的文件如下:

    三. 路由嵌套

    1. 何为路由嵌套?

     目前我们匹配的Home、About、User等都属于底层路由,我们在它们之间可以来回进行切换;但是呢,我们Home页面本身,也可能会在多个组件之间来回切换:

     比如Home中包括Shops、Monent、Message,它们可以在Home内部来回切换;

     这个时候我们就需要使用嵌套路由,在Home中也使用 router-view 来占位之后需要渲染的组件;

    2. 实操

    (1). 路由配置文件

      需要在home组件下增加children节点,在里面配置相应的子路由。

    核心代码:

    const routes = [
        // 空路径自动跳转到Home组件
        {
            path: "/",
            redirect: "/home"
        },
        // 下面匹配规则
        {
            path: '/home',
            name: 'Home',
            component: Home,
            children: [
                //默认显示
                {
                    path: '',
                    redirect: '/home/message'
                },
                {
                    path: 'message',
                    component: () => import('../views/HomeMessage.vue')
                },
                {
                    path: 'monent',
                    component: () => import('../views/HomeMonent.vue')
                },
                {
                    path: 'shops',
                    component: () => import('../views/HomeShops.vue')
                }
            ]
        },
        {
            path: '/about',
            name: 'About',
            component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
        },
        {
            path: '/user',
            name: 'User',
            component: () => import( /* webpackChunkName: "user" */ '../views/User.vue')
        }
    ]

    (2). Home组件

      通过router-link进行子页面的跳转,通过router-view进行占位。

    <template>
        <div>
            我是Home组件
            
            
            <div class="home">
                <router-link to="/home/message">消息</router-link>
                <router-link to="/home/monent">动态</router-link>
                <router-link to="/home/shops">商品</router-link>
            </div>
    
            <!-- 路由占位符 -->
            <router-view></router-view>
        </div>
    </template>
    
    <script>
        import { ref } from 'vue';
    
        export default {
            setup() {
    
            }
        }
    </script>
    
    <style scoped>
        .home {
            margin: 40px 0;
        }
        .router-link-active {
            color: green;
            font-weight: bold;
        }
    </style>
    View Code

    (3). 最终效果

     相关地址:http://localhost:8080/home/message   http://localhost:8080/home/monent   http://localhost:8080/home/shops

    四. 动态路由剖析

    1. 路由的其它属性

     name属性:路由记录独一无二的名称;

     meta属性:自定义的数据

    2. 动态匹配规则

     很多时候我们需要将给定匹配模式的路由映射到同一个组件:

     例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但是用户的ID是不同的;

     在Vue Router中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数

    3. 获取动态路由的值

    (1). 在template模板中

     直接通过:$route.params.xxx来获取

        <div>
            我是User组件
            <div>我是传递过来的id值:{{$route.params.id}}</div>
        </div>

    (2). 在created之类的生命周期中

     通过 this.$route.params.xxx 获取值

    created() {
                console.log(this.$route.params);
                console.log(`我是created声明周期中获取的值${this.$route.params.id}`)
            },

    (3). 在setup()中

     在setup中,我们要使用 vue-router库给我们提供的一个hook useRoute(注意:不是useRouter);该Hook会返回一个Route对象,对象中保存着当前路由相关的值;

    <script>
        import { useRoute } from 'vue-router';
    
        export default {
            setup() {
                const route = useRoute();
                console.log(`我是setup中获取的值${route.params.id}`)
            }
        }
    </script>

    PS:匹配多个参数

    4. 配置NotFound页面 

    (1). 作用

     对于那些没有匹配到的路由,我们通常会匹配到固定的某个页面,比如NotFound的错误页面中,这个时候我们可编写一个动态路由用于匹配所有的页面;

    (2). 实操

    A. 在所有路由规则的最后,配置如下代码

    {
            // 表示上面所有路径都匹配不到
            path: "/:pathMatch(.*)",
            component: () => import("../views/NotFound.vue")
        }

    B. 在NotFound页面通过 $route.params.pathMatch 获取到传入的参数

    <template>
        <div>
            我是NotFound页面
            <div>{{$route.params.pathMatch}}</div>
        </div>
    </template>

    C. 输入地址:http://localhost:8080/user/134543/testkk/3545    ,如下:

    PS:

    五. 相关Api

    1. 页面的跳转push

    (1) methods中

     通过this.$router.push实现。 

    methods: {
                jumpTo1() {
                    this.$router.push('/about');
                }
            }

    (2). setup中

     需要引入 userRouter (注:不是userRoute) 这个hooks来实现。

    <script>
        import { useRouter } from 'vue-router';
    
        export default {
            setup() {
                var router = useRouter();
                const jumpTo2 = () => router.push('/user/10086');
                
                return{
                    jumpTo2
                }
            }
        }
    </script>

    2. query的方式传参和接收

    页面传值代码

        import { useRouter } from 'vue-router';
        export default {
            setup() {
                var router = useRouter();// 测试传参2(query的方式)
                const jumpTo3=() => {
                    router.push({
                        path: '/home/test2',
                        query: { name: 'ypf', age: 18 }
                    })
                };
    
                return {
                    jumpTo3
                }
            }
        }

    页面接收代码

    <script>
        import { useRoute } from 'vue-router';
    
        export default {
            setup() {
                
                const route=useRoute();
                
                // 1. query类型的接收
                console.log(route.query)
                console.log(route.query.name,route.query.age)
    
            }
        }
    </script>

    3. replace替换当前位置

    4. 页面的前进和后退

     

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    六、显式锁和AQS
    五、原子操作(CAS)
    四、线程的并发工具类
    BZOJ 2176 Strange string ——最小表示法
    BZOJ 2882 工艺 ——后缀自动机 最小表示法
    Codeforces Round #401 (Div. 2)
    BZOJ 2331 [SCOI2011]地板 ——插头DP
    BZOJ 2005 [Noi2010]能量采集 ——Dirichlet积
    BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP
    BZOJ 1072 [SCOI2007]排列perm ——状压DP
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/15413601.html
Copyright © 2011-2022 走看看