使用命令npm i vue-router
下载;
在src
文件夹下,创建一个router
文件夹,里面创建一个index.js
文件,里面存放路由的配置信息;
import Vue from 'vue'
import VueRouter from 'vue-router'
// 全局导入,本质将VueRouter挂在到Vue的原型对象上
Vue.use(VueRouter)
const router=new VueRouter(options)
mode表示路由模式,常使用的layout模式有两种,一种是hash
、一种是 history
。两者的具体使用及区别如下->传送门
routes用来配置路由信息,值为一个数组,数组的每个元素为一个路由映射规则。
[
{
path:'路径',
component:组件名
}, // 添加一条路由
{
path:'路径',
redirect:'新路径'
}, // 路由重定向-->也就是说若是输入的是路径,自动跳转到新路径页面
{
path:'路径',
component:组件名,
children:[
{...子路由}
] // 嵌套路由
}
...
]
import index from './index'
const routes = [
{path:'/index', component:index}
]
const router = new VueRouter({routes})
需求场景:仅需修改组件下的某部分,并不需要修改整个页面;
步骤
children
属性(是一个数组
)语法
加父路径加/,不加父路径不加/
举例说明
{
path:'/test',
component:test,
// 默认展示 test1组件的内容
redirect:'/test/test1',
children:[
{path:'test1',component:test1},
{path:'test2',component:test2},
{path:'test3',component:test3},
]
},
<template>
<div>
<div>
我是不修改部分
<router-link to='/test/test1'>底部为第一部分</router-link>
<router-link to='/test/test2'>底部为第二部分</router-link>
<router-link to='/test/test3'>底部为第三部分</router-link>
</div>
<router-view></router-view>
</div>
</template>
嵌套路由传参-通过router-view进行传参
<router-view 参数名='参数值'>router-view>
// 子组件
props:{
参数名:{
type:希望参数类型
}
}
有时我们希望用户输入某个路径时,自动跳转到另一个路由中,比如用户输入域名(不带路径)
const routes = [
// 当用户没有输入路径时会自动跳转到登录页
{path:'/', redirect:'/login'}
]
1.语法–配置路由时
{
path:'路经',
component:导入的组件,
meta:{路由元信息},
alias:‘路由别名(另一个可以访问此网页的路经路经)’
}
2.使用
[1]在项目中,一般我们将’/‘路由重定向为’/login’,
{
path:'/',
redirect:'/login'
}
----此时也可以给登录界面起一个别名
{
path:'/login',
alias:'/',
component:()=>import('login.vue')
}
1.定义:路由元信息其实就是在路由配置
的时候给它设置一些额外信息;
2.语法
{
path: '/login',
component: Login,
// ---增加一个meta属性(是一个对象),里面存放配置路由时的额外信息
meta:{
metaPath:'/login',
title:'登录界面',
}
}
3.举例说明-使用路由元信息修改网页标题
其实我们可以在每个路由页面created钩子中去修改页面的标题,但是非常的麻烦,若是页面多的话,每个页面都要写created函数去修改;
在这里我们使用路由后置导航首位+路由元信息去获取修改网页标题,代码如下
# 在配置路由的时候,在路由元信息中添加标题
const routes = [
// 一个对象代表一个映射规则
{
path: '/login',
component: login,
meta: {
title: '登录界面'
}
},
{
path: '/',
redirect: '/login'
},
{
path: '/layout',
redirect: '/layout/question',
component: layout,
children: [
{
path: '/layout/echart',
component: echart,
meta: {
title: '数据列表'
}
},
{
path: '/layout/user',
component: user,
meta: {
title: '用户列表'
}
},
{
path: '/layout/subject',
component: subject,
meta: {
title: '学科列表'
}
},
{
path: '/layout/question',
component: question,
meta: {
title: '题库列表'
}
},
{
path: '/layout/enterprise',
component: enterprise,
meta: {
title: '企业列表'
}
}
]
}
]
# 2.在路由后置导航守卫中,(to是代表当前进入页面的路由信息)通过to.meta.title获取我们为当前页面设置的标题,并设置到document.title。innerHTML中
router.afterEach(to => {
// 给网页添加标题
document.title = to.meta.title
})
我们有时候开发中会把多个路由解析为同一个Vue组件。问题是,Vue默认情况下共享组件将不会重新渲染,如果你尝试在使用相同组件的路由之间进行切换,则不会发生任何变化,此时我们需要传递key来区分,达到刷新的目的
const routes = [
{
path: "/a",
component: MyComponent
},
{
path: "/b",
component: MyComponent
},
];
<template>
<router-view :key="$route.path">router-view>
template>
路由独享守卫是指在单个路由配置的时候也可以设置的钩子函数,语法如下:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
// 只有调用next函数才会进行路由跳转
}
}
]
})
什么时候才会使用到此钩子函数呢?
情况1: 当前项目的页面为推广页面,用户通过推广链接进入某页面。而大部分页面在进入时需要获取初始化信息,可以将这些逻辑提取在beforeEnter
中,那个页面需要获取在路由中进行配置;
情况2:某些页面进入之前需要进行检测是否有权限,可以在此进行配置
// 由于我们在入口文件中需要将路由对象挂在到根实例中,所以在此处需要导出(此处使用的默认导出)
export default router;
//导入路由
import router from '@/router/index.js';
new Vue({
//挂载路由
router,
render: h => h(App),
}).$mount('#app')
[5]路由出口
在App.vue
主组件中路由出口–相当于占位符,那里使用写哪里;
<router-view></router-view>
检查路由是否配置成功,可以在App.vue中写一个点击看是否报错;
一般不报错说明我们配置的路由是正确的!
router-link 是已经全局注册过的自定义组件,支持用户在具有路由功能的应用中(点击)导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的 a 标签,可以通过配置 tag 属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名
优点:可以使Vue Router在不重新加载页面
的情况下更改URL,处理URL以及生成编码;
属性
to:表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象
replace:属性值为boolean值,默认为false;若是值为true,当点击时,会调用 router.replace() 而不是 router.push(),跳转后不会在 history 留下记录
event:声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组
<router-link to='/test/test2' event='mouseover'>底部为第二部分router-link>
active-class:设置 链接激活时使用的 CSS 类名;
tag:有时候想要 router-link 渲染成某种标签,例如 < li v-pre>,可以使用tag属性 tab=‘li’;
可以通过query,params携带参数;
2.使用router的实例方法来实现
this.$router.push('路经')
$router.push('路经')
router.push('路经')
$router
与$route
的区别总的来讲$router是用来操作路由的, $route是用来获取路由信息的
$router是VueRouter的一个实例,他包含了所有的路由信息及功能,包括路由的跳转方法,钩子函数等,也包含一些子对象;
query传参方式是将参数拼接在路由url上进行传参;
语法1(简写)
this.$router.push('路由url?参数名1=参数值1&参数名2=参数值2')
语法2
this.$router.push({
path:'路由url',
query:{
参数名1:参数值1
参数名2:参数值2
...
}
})
接收
参数会存入到当前路由信息中,也就是说$route
或 $router.currentRoute
中都可以获取到
// 当前页面$route
this.$route.query 为一个对象,可以通过点语法或[]语法获取指定参数
特点
params路由传参是配合路由name属性进行传参
语法
配置路由name属性
{path:'路由url', component:组件, name:'组件名'}
传参
this.$router.params({
name:'路由名',
params:{
参数名1:参数值1
参数名2:参数值2
...
}
})
接收
参数会存入到当前路由信息中,也就是说在$route
或$router.currentRoute
中都可以获取到
// 当前页面$route
this.$route.params 为一个对象,可以通过点语法或[]语法获取指定参数
特点
语法
[1]配置路由参数
// 这样写相当于当前路由必须携带参数,否则进入不了当前页面
{path:'路由url/:参数名', component:组件}
//这样写加不加参数都可以跳转到当前页面
{path:'路由url/:参数名?', component:组件}
[2]传参:跳转路由时传参(大部分是用于传递一些id之类的–不能使用数组/对象/中文字符)
this.$router.push('路径/参数值')
[3]获取-在相应路由对应的组件获取
this.$route.params.参数名
注意
1.作用:
只要是路由跳转,无论是编程式导航($route.push(‘路径’))或者是手动输入都会跳转到该回调函数中;
全局前置导航守卫就是拦截路由跳转并做一定的判断!
还没有跳转到相应的路由页面!
2.语法
# 实例化对象router.beforeEach(参数是一个异步回调函数)
router.beforEach((to,form,next)=>{
# to 到哪里去(里面存储了要跳转的 ·路由信息·)
// ----path属性存储了跳转的路径(不包含参数 eg:'/layout')
//-----fullPath属性存储了跳转的路径(包含参数)
# form 从哪里来(里面存储了跳转之前的 ·路由信息·)
# next回调函数(决定:能不能跳转,跳转到那里去)
//------若是没有写next,页面会卡死(因为不知道你能不能跳转跳转到那里去)
#若是允许跳转next();
#若是不允许,跳到别的地方next('新路径');
})
3.举例说明
在每次进行路由跳转的时候判断存不存在token
//eg:路由每次跳转之前判断有没有token,若是有允许跳转,若是没有跳转到登录界面
if(to.path==='/login'){
//直接跳转
next();
}else {
//判断是否携带了token
let token=getToken();
if(token){
//若携带的是token
next();
}else{
//不携带就跳转到登录界面
next('/login');
}
}
beforeResolve这个钩子和beforeEach类似,也是路由跳转前触发,参数也是to、from、next三个。
和beforeEach区别为:在 beforeEach 和 组件内 beforeRouteEnter 之后,afterEach之前调用。
1.作用:
当执行完路由跳转之后执行的钩子;
已经跳转到相应的路由(页面)
2.语法
router.afterEach((to, from) => {
# to中存储了当前页面的 ·路由信息·
//-------fullPath(全路径)
//-------path(路径)
--------------------区别:全路径携带参数,路径不携带参数
//params----params类型的参数
//query=---query类型的参数
--------------------
//meta:路由元信息
#----就是在路由配置的时候给它设置一些额外信息;
#----若是没有额外信息,to.meta是一个空的对象
})
3.举例说明—使用后置守卫设置路由标题
/权限控制---路由后置守卫
router.afterEach(to => {
window.document.title= to.meta.title;
})
#修改标题window.document.title='值'
在还没有进入该组件之前触发,在渲染该组件的对应路由被confirm前调用,此时不能获取组件实例 this,因为当守卫执行前,组件实例还没被创建,但是可以通过传一个回调给next来访问组件实例,在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数,即上文参数中提到的next((vm)=>{})。
beforeRouteEnter: function(to, from, next) {
// 若是想获取实例对象及数据,可以在next回调函数中获取
next(vm=>{
})
}
组件更新守卫在动态路由中使用,由于动态路由中切换路由的时候,由于绑定的是同一个组件因此在不会在重新渲染,但是为了可以让组件中的内容重新渲染,有两种方法第一种使用watch监听,这种需要使用props写法,另一种就是在beforeRouteUpdate中定义,其会监听到动态路由的改变,因此可以在这个钩子中获取异步动态路由对应的数据,举例来说,对于一个带有动态参数的路径/example/:id,在/example/1和/example/2之间跳转的时候,由于会渲染同样的Example组件,因此组件实例会被复用,而这个钩子就会在这个情况下被调用,在这个钩子函数中可以访问组件实例 this。
beforeRouteUpdate: function(to, from, next) {
// ...
}
导航离开该组件的对应路由时调用,可以访问组件实例this,这个离开守卫通常用来禁止用户在还未保存修改前突然离开,该导航可以通过next(false)来取消。
beforeRouteLeave: function(to, from, next) {
// ...
}
路由信息
)meta
:路由元信息进度条插件
nprogress
(progress是进度的意思)
在vue中使用步骤:
$route就是存储了当前路由的配置信息
路由重复跳转的问题
若是在当组件又跳转到当前组件就会报错;
—直接复制错误,搜索复制即可;
// 就是在路由的原型上加上.catch方法
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}