一、为什么在setup中无法使用beforeRouteEnter
根据vue-router的官方文档,onBeforeRouteLeave和onBeforeRouteUpdate作为组合式 API 函数公开,但并没有对beforeRouteEnter进行公开,所以我们在setup中并不能直接使用beforeRouteEnter。
二、通过新建一个<script lang="ts"></script>标签来解决
1、代码如下
<template>
<div class="setup-router">SetupRouter</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import type { ComponentPublicInstance } from 'vue';
// 基于ComponentPublicInstance类型对组件的类型进行扩展,添加了handleRouter方法
interface VmInstance extends ComponentPublicInstance {
handleRouter(): void;
}
// 定义vue组件
export default defineComponent({
beforeRouteEnter(to, from, next) {
console.log(to, '=========to========');
console.log(from, '=========from========');
next((vm) => {
// beforeRouteEnter 守卫 不能 访问 this,
// 因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
// 不过,可以通过传一个回调给 next 来访问组件实例。
// 在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数
// 这样在组件被创建之前,就能调用组件内部定义的 handleRouter 方法
console.log(vm, '================vm============');
const vmInstance = vm as VmInstance;
vmInstance.handleRouter();
});
},
});
</script>
<script setup lang="ts">
defineOptions({
name: 'SetupRouter',
});
// 当路由即将进入该组件时被调用
const handleRouter = () => {
console.log('beforeRouteEnter的使用');
};
// 使用 <script setup> 的组件是默认关闭的
// 即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。
// 所以需要 defineExpose 函数将 handleRouter 方法暴露出去
defineExpose({ handleRouter });
</script>
<style scoped></style>