当前位置: 首页 > article >正文

2024.10月21日- Vue Router路由管理器

Vue Router路由管理器

一、路由的理解

1)什么是路由?
  • 一个路由就是一组映射关系(key - value)

  • key 为路径,value 可能是 function 或 component

2)路由分类
  • 后端路由:

理解:value 是 function,用于处理客户端提交的请求
工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
  • 前端路由:

理解:value 是 component,用于展示页面内容
工作过程:当浏览器的路径改变时,对应的组件就会显示
3)vue-router的理解

vue 的一个插件库,专门用来实现SPA 应用

4)对SPA应用的理解
  • 单页 Web 应用(single page web application,SPA)

  • 整个应用只有一个完整的页面

  • 点击页面中的导航链接不会刷新页面,只会做页面的局部更新

  • 数据需要通过ajax请求获取

二、 Vue-router的基本应用及其入门案例

2.1 路由插件说明

npm i vue-router@xxx

扩展:

查看最新版本号: npm view 插件包名 version
查看所有的历史版本:npm view 插件包名 versions
查看安装的版本号:npm ls 插件包名

注意:

2022年2月7日以后,vue-router的默认版本为4.x版本,而vue-router-4.x只能在vue3中使用、
vue-router-3.x才能在vue2中使用

2.2 入门案例

在这里我们借助bootstrap.css样式表,来简单设计一下样式.

1. 在public下创建css文件夹,将bootstrap.css放进去
2. 在index.html文件中,引入bootstrap.css
  <link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">

第一步:在App.vue里准备模版

<template>
 <div>
        <div class="row">
            <div class="col-xs-offset-2 col-xs-8">
                <div class="page-header">
                    <h2>导航</h2>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2 col-xs-offset-2">
                <div class="list-group">
                    <a class="list-group-item" href="./food.html">food</a>
                    <a class="list-group-item active" href="./movie.html">movie</a>
                    <a class="list-group-item" href="./picture.html">picture</a>
                </div>
            </div>
            <div class="col-xs-6">
                <div class="panel">
                    <div class="panel-body">
                        ???????
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
  export default {
      name:'App',
  }
</script>

第二步:准备三个组件

Food.vue

<template>
  <h2>我是Food里的内容</h2>
</template>

Movie.vue

<template>
  <h2>我是Movie里的内容</h2>
</template>

Picture.vue

<template>
  <h2>我是Picture里的内容</h2>
</template>

第三步:在src/router/index.js里,定义路由组件,并暴露

//该文件用于创建整个应用的路由器
import VueRouter from "vue-router";
​
//引入组件
import Food from '../components/Food.vue'
import Picture from '../components/Picture.vue'
import Movie from "../components/Movie.vue";
​
//创建一个路由器
export default new VueRouter({
    routes: [
        {
            path: '/food',
            component: Food
        },
        {
            path: '/picture',
            component: Picture
        },
        {
            path: '/movie',
            component: Movie
        }
    ]
})

第四步:在main.js引入相关插件,自定义的路由组件

import Vue from 'vue'
import App from './App.vue'
//引入路由插件
import VueRouter from 'vue-router'
//引入路由组件 src/router/index.js
import Router from './router'

Vue.config.productionTip = false
//使用路由插件
Vue.use(VueRouter)

const vm = new Vue({
  render: h => h(App),
  // 注册
  Router
}).$mount('#app')

第五步:修改App.vue里的代码

<!-- 原始html中我们使用a标签实现页面跳转 -->
<!-- <a class="list-group-item" href="./food.html">food</a>
<a class="list-group-item active" href="./movie.html">movie</a>
<a class="list-group-item" href="./picture.html">picture</a> -->
<!-- Vue中借助router-link标签实现路由的切换,    实际上还是被浏览器翻译成a标签 -->
<router-link class="list-group-item" active-class="active" to="/food">food</router-link>
<router-link class="list-group-item" active-class="active" to="/movie">movie</router-link>
<router-link class="list-group-item" active-class="active" to="/picture">picture</router-link>
​
<div class="panel-body">
   <!-- 指定组件的呈现位置 -->
   <router-view></router-view>
</div>

2.3 案例总结和注意事项

1)路由插件的使用

  • 安装vue-router,命令:npm i vue-router

  • 应用插件:Vue.use(VueRouter)

  • 编写路由实例对象的配置项,管理一组一组的路由规则

  • 实现切换(active-class可配置高亮样式):

<router-link active-class="active" to="/about">About</router-link>
  • 指定展示位:<router-view></router-view>

2)几个注意事项

  1. 路由组件通常存放在pages或者views文件夹,一般组件通常存放在components文件夹

    `src/pages/Home.vue`:
    `src/pages/About.vue`:
    `src/router/index.js`:
  2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载

  3. 每个组件都有自己的$Router属性,里面存储着自己的路由信息

  4. 整个应用只有一个Router,可以通过组件的$Router属性获取到

三、 多级(嵌套)路由

3.1 简介

没有嵌套的路由,称之为一级路由。路由也可以嵌套的,俗称嵌套路由,或者是多级路由。我们可以配置到6级,再深层的路由就没有必要了,其实4,5,6级路由用的都不怎么多。

我们可以使用children配置项,来配置多级路由,

//...
routes:[
   //...
    {
        path:'/movie',
        component:Movie,
      //通过children配置子级路由
        children:[ 
            {
            path: 'actionFilm',//此处一定不要写斜杠
            component: ActionFilm
            },
            {
                path:'comedyFilm ', //此处一定不要写斜杠
                component:ComedyFilm
            }
        ]
    }
   //...
]
//... 

3.2 案例演示:给一级路由Movie添加二级路由

第一步:修改Movie.vue的template

<div>
   <h2>我是movie里的内容</h2>
   <div>
      <ul class="nav nav-tabs">
         <li>
            <a class="list-group-item active" href="./actionFilm.html">动作电影</a>
         </li>
         <li>
            <a class="list-group-item" href="./comedyFilm.html">喜剧电影</a>
         </li>
      </ul>
      <ul>
         <li>
            <a href="/detail">男儿本色</a>&nbsp;&nbsp;
         </li>
         <li>
            <a href="/detail">杀破狼2</a>&nbsp;&nbsp;
         </li>
         <li>
            <a href="/detail">精武英雄</a>&nbsp;&nbsp;
         </li>
      </ul>
   </div>
</div>

第二步:创建子路由组件ActionFilm.vue。

<template>
    <ul>
      <li><a href="./detail">男儿本色</a>&nbsp;&nbsp;</li>
      <li><a href="./detail">杀破狼2</a>&nbsp;&nbsp;</li>
      <li><a href="./detail">精武英雄</a>&nbsp;&nbsp;</li>
   </ul>
</template>

<script>
   export default {
      name: "ActionFilm",
   };
</script>

<style>
</style>

第三步:创建子路由组件ComedyFilm.vue

<template>
  <ul>
    <li><a href="./detail">夏洛特烦恼</a>&nbsp;&nbsp;</li>
    <li><a href="./detail">三傻大闹宝莱坞</a>&nbsp;&nbsp;</li>
    <li><a href="./detail">唐珀琥点秋香</a>&nbsp;&nbsp;</li>
  </ul>
</template>
​
<script>
export default {
  name: "ComedyFilm",
};
</script>
​
<style>
</style>

3.3 内容总结

1)配置路由规则,使用children配置项

//...
routes:[
   //...
    {
        path:'/movie',
        component:Movie,
      //通过children配置子级路由
        children:[ 
            {
                path: 'actionFilm',//此处一定不要写斜杠
                component: ActionFilm
            },
            {
                path:'comedyFilm ', //此处一定不要写斜杠
                component:ComedyFilm
            }
        ]
    }
   //...
]
//...

2)跳转(要写完整路径):

<router-link class="list-group-item" active-class="active" to="/movie/actionFilm">动作电影</router-link>

四、 路由的query参数

ActionFilm.vue

<template>
  <ul>
    <li v-for="film in films" :key="film.id">
      <!-- 跳转路径,并携带参数query:to的字符串写法:-->
      <!-- <router-link :to="`/movie/actionFilm/detail?id=${film.id}&name=${film.name}&intro=${film.intro}`">{{ film.name }}</router-link -->
      <!-- 跳转路径,并携带参数query:to的对象写法:-->
      <router-link
        :to="{
          path: '/movie/actionFilm/detail',
          query: {
            id: film.id,
            name: film.name,
            intro: film.intro,
          },
        }"
        >{{ film.name }}</router-link
      >&nbsp;&nbsp;
    </li>
    <router-view></router-view>
  </ul>
</template>
​
<script>
export default {
  name: "ActionFilm",
  data() {
    return {
      films: [
        {
          id: 1001,
          name: "男儿本色",
          intro:
            "《男儿本色》是由陈木胜执导,谢霆锋,房祖名,余文乐,吴京,安志杰等演员主演的动作警匪片",
        },
        {
          id: 1002,
          name: "杀破狼",
          intro:
            "《杀破狼2》是由郑保瑞执导,梁礼彦、黄英编剧,吴京、托尼·贾、张晋、任达华主演,古天乐特别出演的动作犯罪片",
        },
        {
          id: 1003,
          name: "精武英雄",
          intro:
            "《精武英雄》是由陈嘉上、叶广俭、林纪陶合作编剧,陈嘉上执导,李连杰、中山忍、钱小豪、蔡少芬、周比利、秦沛、仓田保昭、袁祥仁等人主演的电影",
        },
      ],
    };
  },
};
</script>
​
<style>
</style>

Detail.vue

<template>
<div>
   <h3>电影名:{{ $route.query.name }}</h3>
   <p>内容简介:{{ $route.query.intro }}</p>
   </div>
</template>
​
<script>
   export default {
      name: "Detail",
   };
</script>
​
<style>
</style>

index.js

//该文件用于创建整个应用的路由器
import VueRouter from "vue-router";
​
//引入组件
import Food from '../pages/Food.vue'
import Picture from '../pages/Picture.vue'
import Movie from "../pages/Movie.vue"
import ActionFilm from "../pages/ActionFilm.vue"
import ComedyFilm from '../pages/ComedyFilm.vue'
import Detail from '../pages/Detail.vue'
​
//创建一个路由器
export default new VueRouter({
    routes: [
        {
            path: '/food',
            component: Food
        },
        {
            path: '/picture',
            component: Picture
        },
        {
            path: '/movie',
            component: Movie,
            children: [
                {
                    path: 'actionFilm',
                    component: ActionFilm,
                    children: [
                        {
                            path: 'detail',
                            component: Detail,
                        }
                    ]
                }, {
                    path: 'comedyFilm',
                    component: ComedyFilm
                }]
        }
    ]
})

五、 命名路由

作用:用于简化路由的写法

如何使用:

1)给路由命名

export default new VueRouter({
    routes: [
          //...
        {
            name:"dianying",   //给路由命名
            path: '/movie',
            component: Movie,
            children: [
                {
                    path: 'actionFilm',
                    component: ActionFilm,
                    children: [
                        {
                            name:"xiangqing",   //给路由命名
                            path: 'detail',
                            component: Detail,
                        }
                    ]
                }, {
                    path: 'comedyFilm',
                    component: ComedyFilm
                }]
        }
    ]
})

2)简化写法:

<router-link :to="{ name: 'dianying' }">movie </router-link>
<!-- 跳转路径,并携带参数query:to的字符串写法:-->
<router-link :to="`/movie/actionFilm/detail?id=${film.id}&name=${film.name}&intro=${film.intro}`">
   {{ film.name }}
</router-link>
<!-- 跳转路径,并携带参数query:to的对象写法:-->
<router-link :to="{
        name: 'xiangqing',
      query: {
          id: film.id,
          name: film.name,
          intro: film.intro,
       },}">
   {{ film.name }}
</router-link>

六、 路由的params参数

第一步:在路由里,声明接收params参数

//创建一个路由器
export default new VueRouter({
    routes: [
       //...
        {
            name: "dianying",
            path: '/movie',
            component: Movie,
            children: [
                {
                    path: 'actionFilm',
                    component: ActionFilm,
                    children: [
                        {
                            name: "xiangqing",
                            path: 'detail/:id/:name/:intro',  //使用站位符声明要接受params参数
                            component: Detail,
                        }
                    ]
                }, {
                    path: 'comedyFilm',
                    component: ComedyFilm
                }]
        }
    ]
})

第二步: 传递参数

方式1:
<router-link :to="`/movie/actionFilm/detail/${film.id}/${film.name}/${film.intro}`">
   {{ film.name }}
</router-link>
方式2:
<router-link :to="{
          //   path: '/movie/actionFilm/detal',   这种写法会让路由失效
          name: 'xiangqing',
          params: {
            id: film.id,
            name: film.name,
            intro: film.intro,
          },
        }">{{ film.name }}</router-link>

注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置项

七、 路由的props配置项

//创建一个路由器
export default new VueRouter({
        //...
        {
            name: "dianying",
            path: '/movie',
            component: Movie,
            children: [
                {
                    path: 'actionFilm',
                    component: ActionFilm,
                    children: [
                        {
                            name: "xiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            //第一种写法:props的值为对象,该对象的key-value最终都会以props形式传给对应的组件
                            // props: { id: 1001, name: '电影名', intro: 'hahah' }
                            // 第二种写法:props的值为true, 则会把路由的params参数形式的数据传给对应的组件
                            // props: true
                            // 第三种写法:props值为函数,该函数返回的对象中的每一组KV都会通过props形式传给对应的组件
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                },
                   //...
             ]
        }
    ]
})

Detail.vue

<template>
<div>
   <!--  可以直接使用props配置项里的参数名字了-->
   <h3>电影名:{{ name }}</h3>
   <p>内容简介:{{ intro }}</p>
   </div>
</template>
​
<script>
   export default {
      name: "Detail",
      //   在组件中,添加props配置项
      props: ["id", "name", "intro"],
      mounted() {
         console.log(this.$route);
      },
   };
</script>
​
<style>
</style>

八、 router-link的replace属性

用户:在路由跳转时,来替换掉浏览器历史记录的上一条记录。

浏览器的历史记录有两种写入方式:push和replace,其中push是追加历史记录,replace是替换当前记录。

路由跳转时候默认为push方式

开启replace模式:

完整写法:
<router-link :replace='true' ...>Movie</router-link>
简写方式:
<router-link replace ...>Movie</router-link>

九、 路由缓存功能

用途:让不展示的路由组件保持挂载,不被销毁(默认是要销毁的)

<!-- 在router-view外,套一个标签keep-alive, 默认是该处的路由都具有缓存功能
include属性: 用于配置个别路由具有缓存功能,配置路由组件的name属性的值,多个名字使用逗号分开即可
-->
<keep-alive include="ActionFilm,ComedyFilm">
   <router-view></router-view>
</keep-alive>
或者
<keep-alive :include="['ActionFilm','ComedyFilm']">
   <router-view></router-view>
</keep-alive>

十、 编程式路由导航

10.1 简介

之前,我们都是借助<router-link>标签来实现路由的跳转,但是这个标签最终都会被翻译成<a>标签。只能使用这一种,显然不够灵活。

那有没有更加灵活的方式呢?

有,就是使用编程式路由导航。其实就是使用$Router实例上的这些方法,来灵活的控制路由跳转。因为在 Vue 实例内部,你可以通过$Router 访问路由实例。因此你可以调用实例上的相关方法

this.$Router.push('/pages/router/router1')
this.$Router.replace()
this.$Router.forward() //前进
this.$Router.back() //后退
this.$Router.go() //可前进也可后退

10.2 案例演示

banner.vue

<template>
    <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
            <h2>导航</h2>
            <button @click="back">后退</button>
            <button @click="forward">前进</button>
            <button @click="test">测试一下go</button>
        </div>
    </div>
</template>
​
<script>
    export default {
        name: 'Banner',
        methods: {
            back() {
                this.$router.back()
            },
            forward() {
                this.$router.forward()
            },
            test() {
                this.$router.go(2)
            }
        }
    }
</script>
​
<style></style>

index.js

//该文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import Food from '../pages/Food.vue'
import Picture from '../pages/Picture.vue'
import Movie from "../pages/Movie.vue"
import ActionFilm from "../pages/ActionFilm.vue"
import ComedyFilm from '../pages/ComedyFilm.vue'
import Detail from '../pages/Detail.vue'

//创建一个路由器
export default new VueRouter({
    routes: [
        {
            path: '/food',
            component: Food
        },
        {
            path: '/picture',
            component: Picture
        },
        {
            name: "dianying",
            path: '/movie',
            component: Movie,
            children: [
                {
                    path: 'actionFilm',
                    component: ActionFilm,
                    children: [
                        {
                            name: "dongzuodianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            //第一种写法:props的值为对象,该对象的key-value最终都会以props形式传给对应的组件
                            // props: { id: 1001, name: '电影名', intro: 'hahah' }
                            // 第二种写法:props的值为true, 则会把路由的params参数形式的数据传给对应的组件
                            // props: true
                            // 第三种写法:props值为函数,该函数返回的对象中的每一组KV都会通过props形式传给对应的组件
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }, {
                    path: 'comedyFilm',
                    component: ComedyFilm,
                    children: [
                        {
                            name: "xijudianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }]
        }
    ]
})

comedyFilm.vue

<template>
    <div>
        <ul>
            <li v-for="film in films" :key="film.id"><router-link replace :to="{
                //   path: '/movie/actionFilm/detal',   这种写法会让路由失效
                name: 'xijudianyingxiangqing',
                params: {
                    id: film.id,
                    name: film.name,
                    intro: film.intro,
                },
            }">{{ film.name }}</router-link>&nbsp;&nbsp;
                <button @click="showPush(film)">push查看</button>
                <button @click="showReplace(film)">replace查看</button>
            </li>
        </ul>
        <router-view></router-view>
    </div>
</template>
<script>
    export default {
        name: "ComedyFilm",
        methods: {
            showPush(film) {
                this.$router.push({
                    name: 'xijudianyingxiangqing',
                    params: {
                        id: film.id,
                        name: film.name,
                        intro: film.intro,
                    }
                })
            },
            showReplace(film) {
                this.$router.replace({
                    name: 'xijudianyingxiangqing',
                    params: {
                        id: film.id,
                        name: film.name,
                        intro: film.intro,
                    }
                })
            }
        },
        data() {
            return {
                films: [
                    {
                        id: 1001,
                        name: "夏洛特烦恼",
                        intro:
                            "夏洛特烦恼",
                    },
                    {
                        id: 1002,
                        name: "三傻大闹宝莱坞",
                        intro:
                            "三傻大闹宝莱坞",
                    },
                    {
                        id: 1003,
                        name: "唐珀琥点秋香",
                        intro:
                            "唐珀琥点秋香",
                    },
                ],
            }
        },
        beforeDestroy() {
            console.log("----ComedyFilm的beforeDestroy----");
        },
    };
</script>

十一、 路由组件的钩子函数

activated和deactivated是路由组件所独有的两个钩子,用于捕获路由组件的激活状态

1. activated路由组件被激活时触发
2. deactivated路由组件失活时触发

案例演示:

<template>
    <ul>
        <li :style="{ opacity }">欢迎学习Vue</li>
        <li v-for="film in films" :key="film.id">
            <!-- 跳转路径,并携带参数query:to的字符串写法:-->
            <!-- <router-link :to="`/movie/actionFilm/detail?id=${film.id}&name=${film.name}&intro=${film.intro}`">{{ film.name }}</router-link -->
            <!-- 跳转路径,并携带参数query:to的对象写法:-->
            <!-- <router-link
        :to="{
          // path: '/movie/actionFilm/detail',
          name: 'xiangqing',
          query: {id: film.id,name: film.name, intro: film.intro, },}">{{ film.name }}</router-link>&nbsp;&nbsp; -->
            <router-link replace :to="{
                //   path: '/movie/actionFilm/detal',   这种写法会让路由失效
                name: 'dongzuodianyingxiangqing',
                params: {
                    id: film.id,
                    name: film.name,
                    intro: film.intro,
                },
            }">{{ film.name }} <input type="text" /></router-link>&nbsp;&nbsp;
        </li>
        <router-view></router-view>
    </ul>
</template>

<script>
    export default {
        name: "ActionFilm",
        data() {
            return {
                opacity: 1,
                films: [
                    {
                        id: 1001,
                        name: "男儿本色",
                        intro:
                            "《男儿本色》是由陈木胜执导,谢霆锋,房祖名,余文乐,吴京,安志杰等演员主演的动作警匪片",
                    },
                    {
                        id: 1002,
                        name: "杀破狼",
                        intro:
                            "《杀破狼2》是由郑保瑞执导,梁礼彦、黄英编剧,吴京、托尼·贾、张晋、任达华主演,古天乐特别出演的动作犯罪片",
                    },
                    {
                        id: 1003,
                        name: "精武英雄",
                        intro:
                            "《精武英雄》是由陈嘉上、叶广俭、林纪陶合作编剧,陈嘉上执导,李连杰、中山忍、钱小豪、蔡少芬、周比利、秦沛、仓田保昭、袁祥仁等人主演的电影",
                    },
                ],
            };
        },
        // mounted() {
        //     this.timer = setInterval(() => {
        //         console.log("-------ActionFile组件被挂在了-------------");
        //         this.opacity -= 0.01
        //         if (this.opacity < 0) {
        //             this.opacity = 1
        //         }
        //     }, 16);
        // },
        // beforeDestroy() {
        //     console.log("----ActionFilm的beforeDestroy----");
        //     clearInterval(this.timer)
        // },
        activated() {
            console.log("-------ActionFile组件 激活了-------------");
            this.timer = setInterval(() => {

                this.opacity -= 0.01
                if (this.opacity < 0) {
                    this.opacity = 1
                }
            }, 16);
        },
        deactivated() {
            console.log("----ActionFilm的失去活力了----");
            clearInterval(this.timer)
        }
    };
</script>

<style></style>

十二、 路由守卫

12.1 全局路由守卫

全局前置路由

//全局前置路由守卫————初始化的时候、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫', to, from)
    if (to.path === '/movie/actionFilm' || to.path === '/movie/comedyFilm') {
        if (localStorage.getItem('school') === 'youcai') {
            next()
        } else {
            alert('学校名不对,无权限查看!')
        }
    } else {
        next()
    }
})

可以在路由元信息的属性中添加数据,用于来定义该路由是否要被验证

const router = new VueRouter({
    routes: [
            //...
        {
            name: "dianying",
            path: '/movie',
            component: Movie,
            children: [
                {
                    name: "dongzuodianying",
                    path: 'actionFilm',
                    component: ActionFilm,
                    meta: { isAuth: true },
                    children: [
                        {
                            name: "dongzuodianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }, {
                    name: "xijudianying",
                    path: 'comedyFilm',
                    component: ComedyFilm,
                    meta: { isAuth: true },
                    children: [
                        {
                            name: "xijudianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }]
        }
    ]
})
​
export default router
​
​
//全局前置路由守卫————初始化的时候、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫', to, from)
    if (to.meta.isAuth) {
        if (localStorage.getItem('school') === 'youcai') {
            next()
        } else {
            alert('学校名不对,无权限查看!')
        }
    } else {
        next()
    }
})

假如有这样的需求,路由跳转后,我们就修改标签页上的主题,我们可以使用前置路由来写,如下:

1.  先添加上每个路由的title,在meta里面
​
​
2. 然后使用前置路由守卫
//全局前置路由守卫————初始化的时候、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫', to, from)
    document.title = to.meta.title || 'xxx系统'
    if (to.meta.isAuth) {
        if (localStorage.getItem('school') === 'youcai') {
            next()
        } else {
            alert('学校名不对,无权限查看!')
        }
    } else {
        next()
    }
})
​

不过,有缺点,这个使用我们就可以使用后置路由守卫了

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || 'xxx系统'
})

12.2 独享路由守卫

在某一个路由里写:

const router = new VueRouter({
    routes: [
    //...
        {
            name: "dianying",
            path: '/movie',
            component: Movie,
            meta: {
                title: "电影频道"
            },
            children: [
                {
                    name: "dongzuodianying",
                    path: 'actionFilm',
                    component: ActionFilm,
                    //通过路由规则,离开该组件时被调用
                    beforeEnter(to, from, next) {
                        console.log('actionFilm--beforeRouteEnter', to, from)
                        if (to.meta.isAuth) {

                            if (localStorage.getItem('school') === 'youcai') {
                                next()
                            } else {
                                alert('学校名不对,无权限查看!')
                            }
                        }
                    },
                    //通过路由规则,离开该组件时被调用
                    beforeRouteLeave(to, from, next) {
                        console.log('About--beforeRouteLeave', to, from)
                        next()
                    },
                    meta: {
                        isAuth: true,
                        title: "动作电影"
                    },
                    children: [
                        {
                            name: "dongzuodianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }, {
                    name: "xijudianying",
                    path: 'comedyFilm',
                    component: ComedyFilm,
                    meta: {
                        isAuth: true,
                        title: "喜剧电影"
                    },
                    children: [
                        {
                            name: "xijudianyingxiangqing",
                            path: 'detail/:id/:name/:intro',
                            component: Detail,
                            props(route) {
                                return {
                                    id: route.params.id,
                                    name: route.params.name,
                                    intro: route.params.intro
                                }
                            }
                        }
                    ]
                }]
        }
    ]
})

export default router

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || 'xxx系统'
})

12.3 组件内路由守卫

//通过路由规则,离开该组件时被调用
beforeRouteEnter (to, from, next) {
   console.log('About--beforeRouteEnter',to,from)
   if(localStorage.getItem('school')==='atguigu'){
      next()
   }else{
      alert('学校名不对,无权限查看!')
   }
},
   //通过路由规则,离开该组件时被调用
   beforeRouteLeave (to, from, next) {
      console.log('About--beforeRouteLeave',to,from)
      next()
   } 

十三、 路由器的两种工作模式

1)对于一个url来说,什么是hash值?

  • #及其后面的内容就是hash值

  • hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器

2)两种工作模式:

  • hash模式:

    • 地址中永远带着#号,不美观

    • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法

    • 兼容性较好 history模式:

  • history模式:

    • 地址干净,美观

    • 兼容性和hash模式相比略差

    • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

3)如何选择模式

在创建路由器时,添加配置项mode, 两个值,一个mode,一个history

//创建一个路由器
const router = new VueRouter({
    mode: 'history',  //...配置工作模式
    routes: [
    //....
       ],
})

 


http://www.kler.cn/news/363656.html

相关文章:

  • 【状态机DP】力扣2786. 访问数组中的位置使分数最大
  • Flutter 12 实现双击屏幕显示点赞爱心多种动画(AnimationIcon)效果
  • 实操 maxkey对接三方文档
  • day7:软件包管理
  • PostGis空间(下):空间连接与空间索引
  • 动手学深度学习9.7. 序列到序列学习(seq2seq)-笔记练习(PyTorch)
  • 图文深入介绍oracle资源管理
  • flutter小记
  • Apache Calcite - 查询优化之逻辑优化简介
  • 12.useComponentWillUnmount
  • 【MySQL】提高篇—复杂查询:子查询与嵌套查询
  • 【C++笔记】类和对象(下)
  • 02.05、链表求和
  • 【状态机DP】力扣2786. 访问数组中的位置使分数最大
  • 【大模型】3分钟了解提示(Prompt)工程、检索增强(RAG)和微调
  • 前端埋点(tracking)实现多种方式
  • Electron-(三)网页报错处理与请求监听
  • html小游戏-飞机大战
  • 1024感悟 → 勋章
  • Java项目-基于springboot框架的原创歌曲分享系统项目实战(附源码+文档)
  • 人工智能+医学
  • 【C++篇】C++类与对象深度解析(五):友元机制、内部类与匿名对象的讲解
  • 预训练模型通过 prompt(提示)生成的“软标签”是什么
  • C#从零开始学习(封装(5)
  • JAVA Maven 的安装与配置
  • redis 使用