一、Vue-router之集成
1. 功能
处理前端路由的功能
2. 安装
npm install vue-router --save
3. 集成
在项目中新建两个文件(router文件夹下)
index.js // 路由配置
routes.js // 路由内容
3.1 routes.js
存放路由映射关系,为一个数组
import Component from '@/components/Component.vue'
import Login from '@/components/Login.vue'
export default [
{
path: '/component', // 路径
component: Component // 组件
},
{
path: '/login',
component: Login
}
]
3.2 index.js
存放路由配置
- 3.2.1 方式一:返回一个Router对象,全局import时皆为统一对象,不会自动释放,所以在使用服务端渲染时会导致内存溢出
import Router from 'vue-router'
import routes from './routes'
// 使用Router
Vue.use(Router)
export default new Router({
routes // 路由配置
})
- 3.2.2 方式二:返回一个方法,每次import创建一个新的Router
import Router from 'vue-router'
import routes from './routes'
// 使用Router
Vue.use(Router)
export default () => {
return new Router({
routes // 路由配置
})
}
3.3 main.js
import createRouter from './router'
// 使用导入的createRouter方法创建一个router
const router = createRouter()
// 将router放入new Vue的配置项中
new Vue({
router: router,
})
3.4 App.vue
<template>
<!-- <router-view />的位置显示路由对应的内容 -->
<router-view />
</template>
二、Vue-router之配置
1. routes.js
path
路由路径
component
组件
redirect
路由重定向
import Component from '@/components/Component.vue'
import Login from '@/components/Login.vue'
export default [
{
path: '/',
redirect: '/component' // 将路由重定向
},
{
path: '/component', // 路径
component: Component // 组件
},
{
path: '/login',
component: Login
}
]
2. index.js
routes
路由配置
mode
路由模式,默认哈希路由,带#,history模式无#。
base
基路径
linkActiveClass linkExactActiveClass
<router-link>会带有这两个class,全局配置链接被激活时所展示的样式。
- linkExactActiveClass:路径完全匹配
- linkActiveClass:子集即可
scrollBehavior
scrollBehavior (to, from, savedPosition) {}
- to:路由跳转过程中要前往的路由
- from:路由跳转过程中来自的路由
- 注:to与from都是完整的路由对象
- savedPosition:记录滚动条的位置
parseQuery stringifyQuery
?a=xxx&b=yyy
对象与字符串互相转换
fullback
浏览器不支持history会自动转为hash形式
import Router from 'vue-router'
import routes from './routes'
// 使用Router
Vue.use(Router)
export default () => {
return new Router({
routes, // 路由配置
mode: 'history', // 路由模式
base: '/base/', // 路由前会默认加上‘/base/’
linkActiveClass: 'active-link',
linkExactActiveClass: 'exact-active-link',
// 记录滚动行为
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0}
}
},
// 字符串转对象
parseQuery (query) {},
// 对象转字符串
stringifyQuery (obj) {},
fullback: true
})
}
三、Vue-router之路由参数传递
1. routes.js
name
路由名字
<template>
<router-link :to="{name: 'component'}">app</router-link>
</template>
meta
元信息
children
子路由,在该组件之下的<router-view />
之中显示,嵌套路由
import Component from '@/components/Component.vue'
import Login from '@/components/Login.vue'
export default [
{
path: '/component', // 路径
component: Component, // 组件
name: 'component', // 名字
meta: { // 元信息
title: 'this is app',
description: 'asdasd'
},
children: [ // 子路由
{
path: 'test',
component: Login
}
]
},
{
path: '/login',
component: Login
}
]
2. transition
路由过渡动画
- Component
<template>
<transition name="fade">
<router-view />
</transition>
</template>
- Style
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-to {
opacity: 0
}
3. 参数
可从路由中获取信息
访问路径:/app/123?a=123&b=456
3.1 方法1
- routes.js
{
path: '/app/:id', // /app/xxx
component: Login
}
- Component
export default {
mounted () {
this.$route // 路由的全部信息
this.$route.params // {id:"123"}
this.$route.query // {a:"123", b:"456"}
}
}
3.2 方法2
- routes.js
{
path: '/app/:id', // /app/xxx
props: true // 将id作为props传入
component: Login
}
- Component
export default {
props: ['id']
mounted () {
console.log(this.id) // 123
}
}
props的其他用法
- routes.js
{
path: '/app/:id', // /app/xxx
// 自定义值
props: {
id: '456'
},
// 自定义方法
props: (route) => (
{
id: route.query.b
}
),
component: Login
}
四、Vue-router之导航守卫
1. 命名视图
解决同一组件下两个<router-view />
显示不同内容
- Component
<template>
<router-view />
<router-view name="a"/> // 给router-view一个名字
</template>
- routes.js
component改为components
{
path: '/app',
components: {
default: Component,
a: Login
}
}
2. 导航守卫
2.1 全局导航守卫 main.js
const router = createRouter()
- to:前往路由
- from:来源路由
- next:方法,执行下一步
router.beforeEach((to, from, next) => {
console.log('before each invoked');
next()
})
router.beforeResolve((to, from, next) => {
console.log('before resolve invoked');
next()
})
router.afterEach((to, from) => {
console.log('after each invoked')
})
-
执行顺序
beforeEach => beforeResolve => afterEach -
beforeEach
- 进行数据校验
router.beforeEach((to, from, next) => { // 跳转路径为'/login'时才进行跳转 if (to.fullPath == '/login') { next() } })
- next的写法,和vue-router上定义的props是一样的
next('/login') next({path: '/login'}) next({name: 'Login'})
- 进行数据校验
2.2 路由配置中 routes.js
{
path: '/component',
component: Component,
beforeEnter (to, from, next) {
console.log('app route before enter')
next()
}
}
-
执行顺序
beforeEach => beforeEnter => beforeResolve => afterEach
2.3 组件内部 Component.Vue
export default {
beforeRouteEnter (to, from, next) {
console.log('todo before enter')
next()
},
beforeRouteUpdate (to, from, next) {
console.log('todo update enter')
next()
},
beforeRouteLeave (to, from, next) {
console.log('todo leave enter')
next()
},
}
-
执行顺序
beforeRouteLeave(上一路由) => beforeEach => beforeEnter => beforeRouteEnter / beforeRouteUpdate => beforeResolve => afterEach- beforeRouteUpdate
同一个组件在不同路由下显示时触发,mounted()不会触发,需要使用beforeRouteUpdate
- beforeRouteUpdate
- 在beforeRouteEnter中从this中获取数据
beforeRouteEnter (to, from, next) { console.log('todo before enter') next(vm => { console.log(vm); // vm相当于this }) },
- beforeRouteLeave应用场景
控制页面离开,例如当前组件表单做了较大修改,在离开前可询问是否确认离开beforeRouteLeave (to, from, next) { console.log('todo leave enter') if (global.confirm('are you sure?')) { next() } },
3. 异步组件
将component修改为一个方法,即可在访问某个组件时只加载相应代码,而不是一开始就加载全部代码,可提高首页访问速度
{
path: '/component',
component: () => import('/components/Component.vue')
}