二、vue3学习笔记:路由高级
文章目录
- 一、路由组件传参:
- 布尔模式
- 普通页面模式
- 函数模式
- 二、html5 history模式
- 三、导航守卫
- 完整的导航解析流程:
- 全局守卫
- 1)router.beforeEach : 全局前置守卫
- 2)后置钩子
- 专供于页面的守卫
- 1)beforeRouteEnter
- 2) 页面后置钩子:beforeRouteLeave
- 四、路由源信息
- 五、路由的切换动效
- 所有页面动效
- 单独页面动效
一、路由组件传参:
1. 布尔模式
/view/argu.vue
{ { name }}
/router/router.js
{
// 动态路由参数,不管参数是什么,匹配到的都是这个路由对象
path: '/argu/:name',
name: 'argu',
component: () => import('@/views/argu.vue'),
// true表示里面的参数,它会使用router的params作为组建的属性,此时params中
// 有一个name('/argu/:name'),它就会把name传入argu的属性里
props: true
},
2. 普通页面模式
/view/About.vue
<h1>This is an about page</h1> <b>{ { food }}</b>
/router/router.js
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// 懒加载
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props: {
food: 'banana'
}
}
3. 函数模式
router/router.js
{
path: '/',
// 定义别名
alias: '/home_page',
name: 'home',
component: Home,
// 函数模式
props: router => {
}
}
/views/Home.vue
{ { food }}
网址 : http://localhost:8080/\#/?food=banana
- 结果如图:
二、html5 history模式
- 使用history的一些api来做无刷新页面的一些跳转,没有#
如果使用history模式,所有匹配不到url的静态资源都会指向index.html
应该在router.js里面增加一个匹配所有路径的路由 router/index.js
import Vue from ‘vue’
import Router from ‘vue-router’
import routes from ‘./router’// Router作为一个插件,需要使用Vue.use()方式将其加载进来
Vue.use(Router)// Router有两个参数:routes和mode
export default new Router({
// 模式
// 在url的# 号后面作变化,页面是不会刷新的
// mode: ‘hash’,
/ 使用history的一些api来做无刷新页面的一些跳转,没有# 如果使用history模式,所有匹配不到url的静态资源都会指向index.html 应该在router.js里面增加一个匹配所有路径的路由 /
mode: ‘history’,
// 路由
routes: routes
})router/router.js
// 根据优先级原则,定义在越上面的,优先级越高,因此,应该定义在最下面
{
path: ‘*’,
component: () => import(‘@/views/error_404.vue’)
}views/error_404.vue
404
三、导航守卫
完整的导航解析流程:
1.导航被触发
2.在失活的组件(即将离开的页面组件)里调用离开守卫 beforeRouteLeave
3.调用全局的前置守卫 beforeEach
4.在重用的组件里调用 beforeRouteUpdate
5.调用路由独享
6.解析异步路由组件
7.在被激活的组件(即将进入的页面组件)里调用 beforeRouteEnter
8.调用全局解析守卫 beforeResolve
9.导航被确认
10.调用全局的后置守卫 afterEach
11.触发DOM更新
12.用创建好的实例调用beforeRouterEnter守卫里传给next的回调函数
1. 全局守卫
1)router.beforeEach : 全局前置守卫
router/router.js
{
path: '/login',
name: 'login',
component: () => import('@/views/login.vue')
},
router/index.js
import Vue from ‘vue’
import Router from ‘vue-router’
import routes from ‘./router’// Router作为一个插件,需要使用Vue.use()方式将其加载进来
Vue.use(Router)// 拎出来单独定义
const router = new Router({
routes
})const HAS_LOGINED = true
// 注册一个全局前置守卫
// to,from,next都是路由对象,to代表即将跳转的页面,from是即将离开的路由对象,next是一个函数
router.beforeEach((to, from, next) => {
if (to.name !== ‘login’) {// 如果已经登陆则跳转
if (HAS_LOGINED) next()
// 如果为登陆,则先登录,里面可以传入name对象,或path,或路径
else next({ name: 'login' })
} else {
if (HAS_LOGINED) next({ name: 'home' })
else next()
}
})// Router有两个参数:routes和mode
// 模式
// 在url的# 号后面作变化,页面是不会刷新的
// mode: ‘hash’,
/ 使用history的一些api来做无刷新页面的一些跳转,没有# 如果使用history模式,所有匹配不到url的静态资源都会指向index.html 应该在router.js里面增加一个匹配所有路径的路由 /
// mode: ‘history’,
// 路由
export default routerviews/login.vue
Login page
2)后置钩子
router/index.js
// 后置钩子,在路由跳转之后进行一些操作,它不能对跳转的页面进行操作,控制,它只是能够处理一些简单逻辑
router.afterEach((to, from) => {
// logining = false
})
2. 专供于页面的守卫
1)beforeRouteEnter
- views/Home.vue
beforeRouteEnter : 组件在确认前被调用
import Home from ‘@/views/Home’
export default [
{path: '/',
// 定义别名
alias: '/home_page',
name: 'home',
component: Home,
// 函数模式 route为参数,代表当前路由对象 如果想要返回一个对象,则以这种方式填写:({})
props: route => ({
food: route.query.food
}),
// 专供于home页的守卫
// to,from,next都是路由对象,to代表即将跳转的页面,from是即将离开的路由对象,next是一个函数
beforeEnter: (to, from, next) => {
if (from.name === 'about') alert('这是从about来的')
else alert('这不是从about来的')
// 注意调用next()跳转页面
next()
}
},
{path: '/login',
name: 'login',
component: () => import('@/views/login.vue')
},
{path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// 懒加载
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props: {
food: 'banana'
}
},
{// 动态路由参数,不管参数是什么,匹配到的都是这个路由对象
path: '/argu/:name',
name: 'argu',
// 参数
params: {
name: 'lison'
},
component: () => import('@/views/argu.vue'),
// true表示里面的参数,它会使用router的params作为组建的属性,此时params中
// 有一个name('/argu/:name'),它就会把name传入argu的属性里
props: true
},
// 嵌套路由
{path: '/parent',
name: 'parent',
component: () => import('@/views/parent.vue'),
// children代表着嵌套在parent里面的子集页面,路径不用写斜线,作为子集会自动补全
children: [
{
path: 'child',
component: () => import('@/views/child.vue')
}
]
},
{path: '/named_view',
// 注意有个s
components: {
// 没有命名则加载default
default: () => import('@/views/child.vue'),
email: () => import('@/views/email.vue'),
tel: () => import('@/views/tel.vue')
}
},
// 重定向路由
{path: '/main',
// redirect: '/'
// redirect: to => {
// console.log(to)
// }
// redirect: 'home'
// redirect: to => {
// return {
// name: 'home'
// }
// }
redirect: to => {
return '/'
}
},
// 根据优先级原则,定义在越上面的,优先级越高,因此,应该定义在最下面
{path: '*',
component: () => import('@/views/error_404.vue')
}
]views/Home.vue : 打印出当前所有实例
// 组件在确认前被调用
beforeRouteEnter(to, from, next) {
next(vm => {
// 打印出当前所有实例
console.log(vm);
})
// 跳转至下一页
next()
},
2) 页面后置钩子:beforeRouteLeave
src/views/Home.vue :页面后置钩子
// 页面后置钩子
beforeRouteLeave(to, from, next) {
const leave = confirm(‘您确定要离开吗?’)
if (leave) next()
else next(false)
},src/views/argu.vue : 在路由发生变化,组件被复用的情况时被调用
{ { name }}
四、路由源信息
meta里面可以存放一些需要定义的信息,比如页面是否需要一些权限,或者一些其他信息,然后在路由前置守卫里做一些处理。
- 以下是一个更改about的title为“关于”,其他页面为“admin”的例子:
src/lib/util.js
export const setTitle = (title) => {
window.document.title = title || ‘admin’
}src/router/router.js
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// 懒加载
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props: {
food: 'banana'
},
meta: {
title: '关于'
}
},
src/router/index.js
// 注册一个全局前置守卫
// to,from,next都是路由对象,to代表即将跳转的页面,from是即将离开的路由对象,next是一个函数
router.beforeEach((to, from, next) => {
to.meta && setTitle(to.meta.title)
if (to.name !== ‘login’) {// 如果已经登陆则跳转
if (HAS_LOGINED) next()
// 如果为登陆,则先登录,里面可以传入name对象,或path,或路径
else next({ name: 'login' })
} else {
if (HAS_LOGINED) next({ name: 'home' })
else next()
}
})
五、路由的切换动效
页面的切换就是一个组件注销,一个组件加载,在vue基础里面有提到组件的过渡,能够为一个组件的显示
和隐藏都设置一个过度效果,同样也能为一个页面设置一个过渡效果。多个组件使用过渡效果需要使用<transition-group></transition-group>
(只需要包住一个视图渲染组件则只需要)包住视图渲染组件<router-view/>
1. 所有页面动效
src/App.vue
还没有评论,来说两句吧...