// 使用 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
// 使用 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
import { createApp } from 'vue'
// 引入路由
import router from './Route/router.ts'
// 引入入库组件
import App from './App.vue'
createApp(App).use(router).mount('#app')
// 当前需求是在 app.vue 里面放置
<template>
<router-view/>
</template>
<!-- 通过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>
查看解析
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)
})
},
}