vue3 之 vue-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 文件,如下图所示:

vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第1张图片

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')

在需要的位置放置

// 当前需求是在 app.vue 里面放置
<template>
  <router-view/>
</template>

到此一个基础路由配置就算是完成了,后面可以根据自己的业务需求进行配置。如下图所示:

vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第2张图片
vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第3张图片

跳转方式

  1. <!-- 通过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>
    
    
  2. 函数式 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'}
    

vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第4张图片

组件路由守卫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>

路由解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

查看解析

vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第5张图片

求助信息

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)
        })
    },
}

vue3 之 vue-router 路由配置、导航守卫,路由跳转、路由参数传递及获取_第6张图片

你可能感兴趣的:(Vue,vue.js,javascript,前端)