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: [
    //....
       ],
})
相关推荐
前端郭德纲11 分钟前
深入浅出ES6 Promise
前端·javascript·es6
就爱敲代码16 分钟前
ES6 运算符的扩展
前端·ecmascript·es6
天天进步201531 分钟前
Lodash:现代 JavaScript 开发的瑞士军刀
开发语言·javascript·ecmascript
王哲晓37 分钟前
第六章 Vue计算属性之computed
前端·javascript·vue.js
假装我不帅40 分钟前
js实现类似与jquery的find方法
开发语言·javascript·jquery
究极无敌暴龙战神X43 分钟前
CSS复习2
前端·javascript·css
风清扬_jd1 小时前
Chromium HTML5 新的 Input 类型week对应c++
前端·c++·html5
Hadoop_Liang1 小时前
Docker Compose一键部署Spring Boot + Vue项目
vue.js·spring boot·docker
Ellie陈1 小时前
Java已死,大模型才是未来?
java·开发语言·前端·后端·python
GISer_Jing2 小时前
React面试常见题目(基础-进阶)
javascript·react.js·前端框架