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: [
    //....
       ],
})
相关推荐
桂月二二27 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
CodeClimb1 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
沈梦研1 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
轻口味2 小时前
Vue.js 组件之间的通信模式
vue.js
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter