这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
本章将接上回从0到Vue3企业项目实战【08.Vue路由基础】 - 掘金 (juejin.cn)继续介绍Vue路由,基础还没看的同学请先阅读上章
1.0 重定向与模式
不难发现当我们在当前页面的根路径的时候,是不展示任何资源的,通常的网页此时我们会展示登录页或者首页,会检查token后决策,需要完成类似的功能就需要用到我们Vue路由进阶的知识,我们先介绍一些路由重定向的相关知识
路由重定向: 匹配path路径后,强制跳转到指定path路径
- 在规则数组中新增一个规则
- 为新增的规则添加上
redirect属性指定重定向的路径
router目录下的index.js中
const routes = [
{
// 路径
path: '/Dt',
// 昵称
name: 'Dt',
// 组件
component: Dt
},
{
path: '/Wz',
name: 'Wz',
// 直接引入方式
component: () => import('../view/Wz.vue')
},
{
path: '/Wz/:name',
// 直接引入方式
component: () => import('../view/Wz.vue')
},
{
path: '/',
// 路由重定向
redirect: "/Dt"
},
{
path: '/Dt/:name',
component: Dt
}
]
可以发现当我们输入根路径的时候,重定向后,展示了我们指定的动态内容
2.0 页面404的配置
目的:404即未找到资源,当我们输入的路径不存在的时候,返回一个404提示页面
- 创建一个
notFind.vue,作为提示页 - 规则数组中,路径
path匹配*(通配符表示任意路径),路径数组从上往下匹配,所以要放在数组最后的位置,并指定组件为创建的提示页
在view路径下创建NotFound.vue页
<template>
<div>404</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
规则数组中
, {
path: '*',
component: () => import('../view/NotFound.vue')
}
效果如图
3.0 路由模式设置
路径的模式分为两种
hash路由 也就是我们现在用的路由形式 会有个#作为分割 即http://localhost:8080/#/Wzhistory路由 则例如http://localhost:8080/Wz这需要上线的服务器支持否则访问的是文件夹路径
设置方法在 new VueRouter中添加一个mode : "history" 默认为hash路由
const router = new VueRouter({
routes, // routes是固定key(传入规则数组)
mode: "history" // 默认为hash路由
})
修改后效果如图
4.0 编程式导航
我们之前学习过声明式导航,是以标签为作为跳转路径方式的,那么我们可以用js代码作为跳转方式吗?
可以的,使用编程式导航即可,相比声明式导航,编程式导航更灵活,而且我们也可以在跳转前做出更多的逻辑判断,编程式导航对比声明式导航更有优势
跳转语法:
- path或name属性任选其一进行跳转]
// 简写
this.$router.push("/Dt")
// or
this.$router.push('Dt')
// 对象作为参数,写其一即可
this.$router.push({
name: 'Dt',
path: '/Dt'
})
测试一下,App.vue中设置一个按钮并注册其事件
<button @click="gotoDT">跳转到动态页</button>
methods: {
gotoDT () {
this.$router.push({
name: 'Dt',
path: '/Dt'
})
}
}
此时我们点击按钮就可以完成跳转,需要注意的是,使用编程式导航并不会触发声明式导航的点击态,就是选中效果没了,如果要做相关效果可能还得做一定的监听来解决
4.1 编程式导航传参
编程式导航传参同样有两种,params与query,并且两种方式可以同时传递过去,需要使用对象的方式来进行跳转时传参
- 方式一
params=> $route.params.参数名 - 方式二
query=> $route.params.参数名
注意: path会自动忽略params
推荐传参时使用name作为跳转
测试代码,App.vue中定义一个文章按钮测试
<button @click="gotoWZ">跳转到文章页</button>
添加method方法代码如下
gotoWZ () {
this.$router.push({
name: 'Wz',
params: {
name: '文章'
},
query: {
name: '文章'
}
})
}
最好不要两个参数同时传递,这会带来代码的冗余,此处只作为Demo了解
两个传参选择其一即可,组件上面获取不论是编程式导航传参还是声明式导航传参效果都是一样的
5.0 路由嵌套
我们不可能使用一级路由来管理所有页面,因为部分页面上存在嵌套关系的,就好比文章页面中可能会有我的文章还有草稿箱两个分页面,要进入该页面我们首先要进入文章页,再由文章页进入该页面的二级页面
这种形式我们称之为路由嵌套,就跟文件夹一样,我们会将业务先分为几个大类也就是一级路由,而大类下再次细分小类也就是我们的二级路由这样层层嵌套形成了我们真正的项目路由
类似于掘金的编辑文章就是如此,在编辑文章路由下有草稿箱二级路由,并嵌套了当前文章id,从而确定我当前编辑的文章到底是哪一篇
ok,现在我们来确定下如何实现二级路由
- 创建所需组件
- 在
view目录下创建draft.vue与myWz.vue文件作为草稿箱与我的文章页作为文章页的二级路由
- 在
- index.js中的规则数组继续配置二级路由
- 一级路由的path是从/开始定义的
- 二级路由在该一级路由的
children为属性名的对象数组中定义,并且二级路由path无需/开头,其余属性与一级路由并无区别
- 添加二级路由挂载点与跳转方法
- 在
Wz.vue文件内创建router-view作为二级路由的挂载点 - 在
Wz.vue文件内添加按钮添加跳转方法
- 在
实践一下
在view文件下创建draft.vue与myWz.vue文件作为子组件,直接输入vue创建模板然后template中写上下面文字区分即可
<div>我的文章</div>
// and
<div>我的草稿箱</div>
router目录下的index.js中规则数组也就是routes添加二级路由规则
const routes = [
{
// 路径
path: '/Dt',
// 昵称
name: 'Dt',
// 组件
component: Dt
},
{
path: '/Wz',
name: 'Wz',
// 直接引入方式
component: () => import('../view/Wz.vue'),
children: [
{
path: 'draft',
component: () => import('../view/wz/draft.vue')
}, {
path: 'myWz',
component: () => import('../view/wz/myWz.vue')
},
]
},
{
path: '/Wz/:name',
// 直接引入方式
component: () => import('../view/Wz.vue'),
children: [
{
path: 'draft',
component: () => import('../view/wz/draft.vue')
}, {
path: 'myWz',
component: () => import('../view/wz/myWz.vue')
},
]
},
{
path: '/',
// 路由重定向
redirect: "/Dt"
},
{
path: '/Dt/:name',
// 路由重定向
component: Dt
}, {
path: '*',
component: () => import('../view/NotFound.vue')
}
]
Wz.vue页面中添加上跳转方法与挂载点
<template>
<div>
<p>{{$route.params.name}}</p>
<router-link to="/Wz/draft">我的草稿箱</router-link>
<router-link to="/Wz/myWz">我的文章</router-link>
<button @click="gotoDraft">我的草稿箱</button>
<button @click="gotoMy">我的文章</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
methods: {
gotoDraft () {
this.$router.push('/Wz/draft')
},
gotoMy () {
this.$router.push('/Wz/myWz')
}
}
}
</script>
<style>
</style>
此时实现效果如图所示
路由嵌套需要注意的就是:
- 规则数组中无需以/开头
- 跳转的时候路径记得从根目录写全
6.0 声明式导航激活类名的区别
当声明式导航被激活时,当前标签会多出两种类名,分别为 router-link-active与router-link-exact-active
router-link-active(模糊匹配)url上的路径值包含当前的声明式导航标签绑定的路径那么当前标签将会有该类名router-link-exact-activeurl上的路径等于当前的声明式导航标签绑定的路径那么当前标签将会有该类名
这也就能解释为什么我们上面的案例跳转二级路由后上面的文章选中状态没了,因为我们上面采用的是在路径上/:name传递参数,会更改url路径,当跳转后url当然与父节点路径不匹配了
7.0 路由守卫
我们在进行一些页面跳转的时候,大部分的应用都会做权限判断,例如没有登录那么则让你登录后再跳转,这些都可以使用路由守卫,也就是在跳转前会触发一个函数,我们通过这个函数来进行权限判断,让他进入他应该进入的页面,这个过程也叫做路由守卫
语法:
- router.beforeEach((to,from,next) => {})
- 三个变量名可以随便叫,这个无所谓位置固定,尽量的见名知义
- 参数一
要跳转到的路由信息-> 目标 - 参数二
从哪里跳转的路由信息-> 来源 - 参数三
函数体next()才会让路由进行正常跳转,next(false)原地停留,next("路径)强制跳转到另一个路由下 - 注意如果不调用
next()那么将停留原地
测试一手,我们用token来表示是否登录,token为空则为登录,测试一下路由守卫的功能
在router目录下的index.js中创建router后写上如下代码
// 路由守卫
// 当需要对于路由权限进行判断时使用路由守卫
let token = ''
router.beforeEach((to, from, next) => {
if (token == '' && to.path == '/Dt/动态') {
alert('请登录')
next(false)
} else {
next()
}
})
此时会发现效果如图
来看看我的其他章节吧,正在长更中
从0到Vue3企业项目实战【01.Vue的基本概念与学习指南】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【02.了解并理解Vue指令以及虚拟Dom】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【03.vue基本api入门】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【04.从vue组件通讯到eventBus以及vuex(附mock接口与axios简单实践)】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【05.vue生命周期】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【06.nextTick使用】 - 掘金 (juejin.cn)
从0到Vue3企业项目实战【07.vue动态组件,组件缓存,组件插槽,子组件直接修改props,自定义指令看这一篇就够了】 - 掘金 (juejin.cn)