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)几个注意事项
-
路由组件通常存放在
pages
或者views
文件夹,一般组件通常存放在components
文件夹`src/pages/Home.vue`: `src/pages/About.vue`: `src/router/index.js`:
-
通过切换,"隐藏"了的路由组件,默认是被销毁掉的,需要的时候再去挂载
-
每个组件都有自己的
$Router
属性,里面存储着自己的路由信息 -
整个应用只有一个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> </li> <li> <a href="/detail">杀破狼2</a> </li> <li> <a href="/detail">精武英雄</a> </li> </ul> </div> </div>
第二步:创建子路由组件ActionFilm.vue。
<template>
<ul>
<li><a href="./detail">男儿本色</a> </li>
<li><a href="./detail">杀破狼2</a> </li>
<li><a href="./detail">精武英雄</a> </li>
</ul>
</template>
<script>
export default {
name: "ActionFilm",
};
</script>
<style>
</style>
第三步:创建子路由组件ComedyFilm.vue
<template> <ul> <li><a href="./detail">夏洛特烦恼</a> </li> <li><a href="./detail">三傻大闹宝莱坞</a> </li> <li><a href="./detail">唐珀琥点秋香</a> </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 > </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>
<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> --> <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> </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: [ //.... ], })