只要有你想要保护的东西,那就拔剑好了
前言
1 router
构造器
VueRouter
import VueRouter from 'vue-router'
// VueRouter 高版本问题
// Error: Redirected when going from “/login” to “/home”
// via a navigation guard
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) {
return originalPush.call(this, location, onResolve, onReject)
}
return originalPush.call(this, location).catch(err => err)
}
const router = new VueRouter({ routes })
属性
options
// 路由信息
// 可筛选出特定路由route,用于跳转拦截
router.options = {
routes: [route]
}
方法
beforeEach
// 路由跳转前触发,此时仍处于当前页面
// 可用于登录拦截
// 可用于跳过测试页面,直接跳转结果页面
router.beforeEach((to, from, next) => {
// 如果没有登录,跳转登录页
if (!token) {
next('/login')
}
// 如果做过测试,跳转结果页
const reportRoute = router.options.routes.find(
route => route.name === 'Report'
)
if (to.name === 'Test' && reportRoute.meta.hasReport) {
next('/report')
}
// next 必须执行,否则无法跳转
// 参数为String, 传path
// 参数为对象,{path, name?, params?, query?}
// 参数为false,阻止跳转
next()
})
2 routes
同步路由
import Home from '@views/Home.vue'
import About from '@views/About.vue'
import NotFount from '@views/NotFount.vue'
const routes = [
{
path: '/',
redirect: '/home' // 默认进入 Home 页面
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about', // 匹配 about 进入 About 页面
name: 'About',
component: About
},
{
path: '*', // 没有匹配以上路由,则进入 NotFount 页面
name: 'NotFount',
component: NotFount
}
}
异步路由
const routes = [
...
{
path: '/home',
name: 'Home',
component: () => import('@views/Home.vue')
},
{
path: '/about', // 匹配 about 进入 About 页面
name: 'About',
component: () =>
// 打包成单独的chunk
// chunk名称为 about
import(/* webpackChunkName: "about" */ '@views/About.vue'),
},
...
}
动态路由
const routes = [
...
{
path: '/product/:id', // param传参
name: 'Product',
component: () => import('@views/Product.vue'),
// 解耦props
// 不使用 this.$route.params.id 取参数
// 直接使用 props:['id'] 接收后,再使用this.id 取参
props: route => ({...route.params})
}
...
}
// 路由跳转
this.router.push({
path: 'product/123'
})
this.router.push({
name: 'Product'
params: {
id: 123
}
})
子路由
const routes = [
...
{
path: '/about',
name: 'About',
component: () =>
import(/* webpackChunkName: "about" */ '@views/About.vue'),
children: [
{
path: '', // 默认进入 profile 子页面
redirect: 'profile'
},
{
// 相对路径
// 使用 path: '/about/profile' 跳转
path: 'profile',
name: 'Profile',
component: () =>
import(/* webpackChunkName: "about" */ '.@views/Profile.vue')
},
{
// 绝对路径
// 直接使用 path: '/posts' 跳转
path: '/posts',
name: 'Posts',
component: () =>
import(/* webpackChunkName: "about" */ '@views/Posts.vue')
}
]
}
...
]
3.route
常规属性
{
// 跳转路由
path: '/home',
// 路由名称
name: 'Home',
// 路径映射的组件
component: Home
}
重定向
{
...
// 默认进入
path: '/',
// 重定向到 Home 页面
redirect: '/home'
...
}
路由解耦
{
...
// 解耦props
// 不使用 this.$route.params.id 取参数
// 直接使用 props:['id'] 接收后,再使用this.id 取参
props: route => ({...route.params})
...
}
路由元
{
...
// 路由信息
// 存储该路由特定变量
meta:{
keepAlive: true,
auth: true,
breadcrums: ['首页', '关于', '个人'],
hasToReport: false
}
...
}
路由拦截
{
path: '/report',
name: 'Report',
component: () =>
import(/* webpackChunkName: "about" */ '../views/Report.vue'),
meta: {
hasToReport: false
},
beforeEnter: (to, from, next) => {
to.meta.hasToReport = true
next()
}
}
4.注意
1.高版本路由,没有catch错误,需做单独处理
2.解耦props后,动态路由须使用 params 传参
3.权限等涉及路由跳转拦截问题,在beforeEach里处理
4.redirect可使用函数
尾声
人挺多了,抓紧我,我可不想把你给弄丢了~
晚安 ^_^
参考链接
往期回顾
- 每天学习一个vue插件(1)——better-scroll
- 每天学习一个vue插件(2)——vue-awesome-swiper
- 每天学习一个vue插件(3)——eslint + prettier + stylelint
- 每天学习一个vue插件(4)——v-viewer
- 每天学习一个vue插件(5)——postcss-pxtorem
- 每天学习一个vue插件(6)——momentjs
- 每天学习一个vue插件(7)——hammerjs
- 每天学习一个vue插件(8)——mcanvas
- 每天学习一个vue插件(9)——MathJax
- 每天学习一个vue插件(10)——Vue-APlayer
- 每天学习一个vue插件(11)——vue-drag-resize
- 每天学习一个vue插件(12)——vue-fullpage
- 每天学习一个vue插件(13)——html2canvas
- 每天学习一个vue插件(14)——vue-pull-to
- 每天学习一个vue插件(15)——vue-content-placeholders
- 每天学习一个vue插件(16)——vue-video-player
- 每天学习一个vue插件(17)——js-file-download
- 每天学习一个vue插件(18)——js-audio-recorder
- 每天学习一个vue插件(19)——vue-treeselect
- 每天学习一个vue插件(20)——progressbar
- 每天学习一个vue插件(21)——ProvidePlugin