最近开发一个功能:在打开主页路由界面时,地址后面可能有query参数,如果有type值就需要进行一些逻辑处理。
为了区分/home
和/home?type=xxx
的情况,常规思路是在组件中使用beforeRouteEnter
方法,判断to.query.type是否存在。
但在实际使用时发现TS+Vue3的模式会导致该方法无效,不会被执行,以下两种方式均无效。
// views/Home/Home.vue
// 方式一
<script lang="ts">
export default {
beforeRouteEnter(to, from, next) {
next((vm) => {
// 通过 `vm` 访问组件实例
});
}
// beforeRouteEnter: function () {}
};
</script>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue';
</script>
// 方式二
<script lang="ts">
import { defineComponent, reactive, ref, watch } from 'vue';
export default defineComponent({
beforeRouteEnter(to, from, next) {
next((vm) => {
// 通过 `vm` 访问组件实例
});
},
setup() {}
});
</script>
经过查阅资料,发现确实存在该问题,因此换了一种思路,使用导航守卫+store的方式。
// router/index.ts
router.beforeEach((to, from, next) => {
if (to.path === '/home') {
if (to.query.type) {
homeStore.setType(to.query.type);
}
}
return next();
});
// store/home.ts
import { defineStore } from 'pinia';
export const useHomeStore = defineStore({
id: 'home',
state: () => ({
type: '',
}),
actions: {
setType(type = '') {
this.type = type;
}
}
});
// views/Home/Home.vue
<script lang="ts" setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useHomeStore } from '@/stores/home';
const router = useRouter();
const homeStore = useHomeStore();
watch(homeStore.type, newVal => {
getInfoByType();
});
cosnt getInfoByType = () => {
if(homeStore.type.length) {
// 这里是查询数据逻辑...
router.push({ path: '/home', replace: true })
homeStore.setType();
}
}
getInfoByType();
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。