最近开发一个功能:在打开主页路由界面时,地址后面可能有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>

聆听TS
108 声望5 粉丝

留有的余味。-Weibo