1. 路由的简单配置和技巧
(1) 在路由地址后面 :name
{
path: '/argu/:name',
component: () => import('@/views/argu.vue')
}
在组件内
<div>
{{ $route.params.name }}
</div>
其中 $route.params.name 就代表地址栏(http://localhost:8080/#/argu/gfz)上的参数 gfz
(2) 嵌套路由
路由配置:
{
path: '/parent',
component: () => import('@/views/parent.vue'),
children: [
{
path: 'child',
component: () => import('@/views/child.vue')
}
]
}
地址栏: http://localhost:8080/#/parent/child
(3)命名路由:
给路由一个name值
{
path: '/',
name: 'home', // name值就是给该路由命名
component: Home
}
此时就能用利用name进行路由跳转
<router-link :to="{name: 'home'}">Home</router-link> |
<router-link :to="{name: 'about'}">About</router-link>
(4)命名视图:
此时想要多个<router-view/>时
<router-view/>
<router-view name="email"/>
<router-view name="tel"/>
路由配置
{
path: '/named_view',
components: {
default: () => import('@/views/child.vue'),
email: () => import('@/views/email.vue'),
tel: () => import('@/views/tel.vue'),
}
}
显示在页面上:
(5)重定向
{
path: '/main',
redirect: '/'
}
或者
{
path: '/main',
redirect: {
name: 'home'
}
}
还可以:
{
path: '/main',
redirect: to => {
return {
name: 'home'
}
}
}
或者:
{
path: '/main',
redirect: to => {
return '/'
}
}
地址栏输入http://localhost:8080/#/main 则 自动会跳转到根目录下
(6)别名
//alias
{
path: '/',
alias: '/home_page',
name: 'home',
component: Home
}
地址栏输入http://localhost:8080/#/home_page则会显示与首页一样的内容
(7)路由跳转
<template>
<div class="home">
<button @click="handleClick('back')">返回上一页</button>
<button @click="handleClick('push')">跳转</button>
<button @click="handleClick('replace')">替换到parent</button>
</div>
</template>
<script>
export default {
name: 'home',
methods: {
handleClick(type){
if(type === 'back'){
this.$router.back(-1);
}
else if(type === 'push'){
this.$router.push({
name: 'parent'
})
}
else if(type === 'replace'){
this.$router.replace({
name: 'parent'
})
}
}
}
}
</script>
其中this.$router.replace()的意思:跳转的页面替换了刚才的页面,返回不到之前的页面
this.$router.push({
name: 'parent',
query: {
name: 'gfz'
}
})
点击跳转按钮:地址栏的地址:http://localhost:8080/#/parent?name=gfz
this.$router.push({
name: 'argu',
params: {
name: 'gfz'
}
})
点击跳转按钮:地址栏的地址:http://localhost:8080/#/argu/gfz
(8)路由props传值
//argu.vue
<template>
<div>
{{ name }}
</div>
</template>
<script>
export default {
name: "argu",
props: {
name: {
type: String,
default: 'gfz'
}
}
}
</script>
{
path: '/argu/:name',
name: 'argu',
component: () => import('@/views/argu.vue'),
props: true
},
此时只需要在地址栏输入http://localhost:8080/#/argu/hhh 则页面就会显示hhh
另一种:
<template>
<div class="about">
<b>{{food}}</b>
</div>
</template>
<script>
export default {
props: {
food: {
type: String,
default: 'apple'
}
}
}
</script>
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props: {
food: 'banana'
}
},
则进入到about页面,该页面会显示 ‘banana’
还有一种:
{
path: '/',
alias: '/home_page',
name: 'home',
component: Home,
props: router => ({
food: router.query.food
})
}
此时在地址栏输入http://localhost:8080/#/?food=banana 则home页面会接受到banana字符串显示在页面上
(9)history模式
export default new Router({
mode: 'history',
})
{
path: '*',
component: () => import('@/views/error_404.vue')
}
(10)导航守卫
(10.1)全局前置守卫(路由跳转前验证登录)
const router = new Router({
routes
})
router.beforeEach((to, from, next) => {
})
export default router
其中to表示即将要去到的路由,from表示从哪来的路由,next是一个函数
接下来完善一下:
const HAS_LOGIN = true;
router.beforeEach((to, from, next) => {
if(to.name !== 'login'){
if (HAS_LOGIN) next()
else next({name: 'login'})
}
else {
if(HAS_LOGIN) next({name: 'home'})
else next()
}
})
(10.2)路由独享守卫 beforeEnter,不是全局路由,只是在该路由配置上的路由守卫
{
path: '/',
alias: '/home_page',
name: 'home',
component: Home,
props: router => ({
food: router.query.food
}),
beforeEnter: (to, from, next) => {
if(from.name === 'about') alert('这是从about页来的')
else alert('这不是从about页来的')
next();
}
},
(10.3)beforeRouteEnter:进入路由之前执行的函数。(在vue组件内调用)
在该函数内,不能用this,因为这个时候还没有创建vue实例
beforeRouteEnter(to, from, next){
//可以写一些代码逻辑
next();
},
(10.4)beforeRouteLeave:离开路由之前执行的函数。(在vue组件内调用)
beforeRouteLeave(to, from, next){
const leave = confirm('您确认要离开吗?');
if(leave) next()
else next(false)
}
(10.5)beforeRouteUpdate:当路由的url地址发生变化时执行的函数。(在vue组件内调用)
beforeRouteUpdate(to, from, next){
console.log(to.name, from.name)
}
(10.6)完整的导航解析流程
①. 导航被触发
②. 在失活的组件(即将离开的页面组件)里调用离开守卫 beforeRouteLeave
③. 调用全局的前置守卫 beforeEach
④. 在重用的组件里调用 beforeRouteUpdate
⑤. 调用路由独享的守卫 beforeEnter
⑥. 解析异步路由组件
⑦. 在被激活的组件(即将进入的页面组件)里调用 beforeRouteEnter
⑧. 调用全局的解析守卫 beforeResolve
⑨. 导航被确认
⑩. 调用全局的后置守卫 afterEach
⑪. 触发DOM更新
⑫. 用创建好的实例调用beforeRouterEnter守卫里传给next的回调函数
(11)路由源信息的使用:
// router/router.js
{
path: '/about',
name: 'about',
component: () => import('@/views/About.vue'),
props: {
food: 'banana'
},
meta: {
title: '关于'
}
},
import {setTitle} from '@/lab/util'
//全局前置守卫
router.beforeEach((to, from, next) => {
to.meta && setTitle(to.meta.title)
})
//util.js
export const setTitle = (title) => {
window.document.title = title || 'admin'
}
此时进入到about页面title会显示'关于',没有设置title的都会显示'admin'
(12)路由的切换动效:
<template>
<div id="app">
<div id="nav">
<router-link :to="{name: 'home'}">Home</router-link> |
<router-link :to="{name: 'about'}">About</router-link>
</div>
<transition-group name="router">
<router-view key="default"/>
<router-view key="email" name="email"/>
<router-view key="tel" name="tel"/>
</transition-group>
</div>
</template>
<style lang="less">
.router-enter{
opacity: 0;
}
.router-enter-active{
transition: opacity 1s ease;
}
.router-enter-to{
opacity: 1;
}
.router-leave{
opacity: 1;
}
.router-leave-active{
transition: opacity 1s ease;
}
.router-leave-to{
opacity: 0;
}
</style>