vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取
vue3.xvue-router 路由配置,导航守卫,路由跳转,路由传参及参数获取
·
安装
// 使用 npm 安装
npm install vue-router
// 使用 yarn 安装
yarn add vue-router
// 可以在 vue-router 末尾添加 @4.x.x , 表示安装对应版本的依赖文件
// 举个🌰
yarn add vue-router@4
// 或者
npm install vue-router@4
在src目录下创建 Route > router.ts 文件,如下图所示:
router.ts 或者 router.js 文件中添加路由配置信息
// 使用 tree-shaking 按需引入
import {
createRouter, // 创建路由
createWebHashHistory, // 使用hash模式
createWebHistory, // 使用浏览器history模式
createMemoryHistory // 用于服务器端渲染
} from "vue-router";
// 一次引入所有的组件(不推荐)
// import HelloWorld from '../components/HellowWorld.vue';
// import PageWatch from '../pages/page-watch'
// 使用路由懒加载,剩下的一些路由相关配置跟vue2基本差不多
const routes = [
{
path: '/n',
// path: '/n/:id', // 动态路由,可以在跳转目标页面用 useRouter 获取对应的参数
name: 'helloworld',
// redirect: '/login' // 重定向自己的目标路由
// alias: '/pp1', 配置路由别名
meta: {
title: '你好啊', // 可以在 main.js 中通过全局前置导航守卫 beforeEach 设置标签页名称
},
component: () => import('@/components/HelloWorld.vue'),
beforeEnter: (to, from, next) => {
console.log('路由独享守卫 to :', to)
console.log('路由独享守卫 from:', from)
next()
},
children: []
},
{path: '/', component: () => import(/* webpackChunkName: "table" */ '@/pages/page-watch.vue')} // 注释部分表示打包时chunk根据table进行分类打包
];
const router = createRouter({
history: createWebHistory(),
routes
});
// 通过全局前置守卫进行设置标签页名称
router.beforeEach((to, from, next) => {
const {meta: {title}} = to;
document.title = title || '自定义名称';
console.log('全局前置守卫', to, from, next);
next()
})
// 全局解析守
router.beforeResolve((to, from, next)=>{
console.log('全局解析守卫', to, from, next)
next()
})
// 全局后置守卫
router.afterEach((to, from, failure) => {
console.log('全局后置守卫', to, from, failure)
// next()
})
// 输出路由对象,可以在 main.js 中引入
export default router
在main.js 中引入并使用
import { createApp } from 'vue'
// 引入路由
import router from './Route/router.ts'
// 引入入库组件
import App from './App.vue'
createApp(App).use(router).mount('#app')
在需要的位置放置 <router-view />
// 当前需求是在 app.vue 里面放置
<template>
<router-view/>
</template>
到此一个基础路由配置就算是完成了,后面可以根据自己的业务需求进行配置。如下图所示:
跳转方式
-
<router-link>
<!-- 通过router-link实现跳转 --> <router-link to="/">跳转1</router-link> <router-link :to="'/'">跳转2</router-link> <router-link :to="{path: '/'}">跳转3</router-link> <router-link :to="{path: '/', query: {query: '123'}}">跳转4</router-link> <router-link :to="{name: 'pageWatch', params: {params: '123'}}">跳转5</router-link>
-
函数式
useRouter
跳转并实现参数传递及接收useRoute
// ---------------- 组件A ---------------------- // 按需引入 vue-router import {useRouter} from 'vue-router' // 路由实例化 const router = useRouter(); const goToPage = () => { // 方式1: // router.push('/') // 方式2,可以携带参数 router.push({ path: '/', query: { bb:'111' } }) // ...(具体使用方法就跟 Vue2 基本没差别) } // ---------------- 组件B ---------------------- // 接收路由传递的参数 import {useRoute} from 'vue-router' const Route = useRoute(); console.log('接收路由参数(Route.query)::',Route.query) console.log('接收路由参数(Route.params)::',Route.params) // {bb: '111'}
组件路由守卫2.x
<script>
export default {
name: 'pageOne',
data() {
return {
msg: '111111'
}
},
created() {
console.log('created::', this.msg)
},
mounted() {
console.log('mounted::', this.msg)
},
methods: {
aaa(route) {
console.log(route)
}
},
beforeRouteEnter(to, from, next) {
console.log('组件内前置导航守卫 beforeRouteEnter :', this,to, from);
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
console.log(next)
next((vm)=>{console.log('组件内前置导航守卫通过回调访问this',vm)})
},
beforeRouteUpdate(to, from, next) {
console.log('组件内更新导航守卫 beforeRouteUpdate :', this,to, from);
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
next()
},
beforeRouteLeave(to, from, next) {
console.log('组件内后置导航守卫 beforeRouteLeave :', this,to, from);
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
next()
}
}
</script>
组件路由守卫3.x
// 实现方式一
<script>
import {ref, reactive} from 'vue'
export default ({
name: 'pageWatch',
data(){
return {
}
},
setup(){
// Do somethings
const msg = ref('这是通过ref定义的一个基本类型的数据')
const myCarObj = reactive({
carName: 'aaa',
price: '20',
color: 'white'
})
// 此处需要return 回去一个对象
return {
msg,
myCarObj
}
},
beforeRouteEnter(to, from, next) {
console.log('组件内前置导航守卫 beforeRouteEnter :', this,to, from);
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
console.log(next)
next((vm)=>{console.log('组件内前置导航守卫通过回调访问this',vm)})
},
beforeRouteUpdate(to, from, next) {
console.log('组件内更新导航守卫 beforeRouteUpdate :', this,to, from);
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
next()
},
beforeRouteLeave(to, from, next) {
console.log('组件内后置导航守卫 beforeRouteLeave :', this,to, from);
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
next()
}
})
</script>
// 实现方式二
// 特别说明: 3.x 里面要使用 beforeRouteEnter 需要采取如下方式
// 单独启用一个 script 里面进行 组件内导航监听
<script>
import { defineComponent } from 'vue'
export default defineComponent({
beforeRouteEnter(to, from, next) {
console.log('组件内前置导航守卫 beforeRouteEnter :', this,to, from);
// Do somethings
next()
}
})
</script>
<script setup>
// Do somethings
</script>
路由解析流程
- 导航被触发。
- 在失活的组件里调用 beforeRouteLeave 守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫(2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
查看解析 🌰
求助信息
onBeforeRouteLeave
, onBeforeRouteUpdate
这两个API在 setup
函数中,并未实现组件内路由监听,希望各位朋友能够指点一二。
场景一
import {onBeforeRouteLeave,onBeforeRouteUpdate} from 'vue-router'
<script setup>
// 此方式并未在控制台中输出打印信息
onBeforeRouteLeave((to,from) => {
console.log(111,to,from)
})
onBeforeRouteUpdate((to,from) => {
console.log(222,to,from)
})
</script>
场景二
import {onBeforeRouteLeave,onBeforeRouteUpdate} from 'vue-router'
export default {
setup() {
// 与 beforeRouteLeave 相同,无法访问 `this`
onBeforeRouteLeave((to, from) => {
console.log(1111111,to,from)
})
// 与 beforeRouteUpdate 相同,无法访问 `this`
onBeforeRouteUpdate(async (to, from) => {
console.log(22222222,to,from)
})
},
}
更多推荐
已为社区贡献1条内容
所有评论(0)