index.vue 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. <template>
  2. <router-view class="app-page" v-slot="{ Component, route }">
  3. <RouterTransition :transition-name="state.transitionName" @leave="onLeave" @after-enter="onAfterEnter">
  4. <!-- 缓存组件,前进刷新,后退缓存 -->
  5. <keep-alive :exclude="state.excludeViews">
  6. <component :is="handleComponent(Component, route)" :key="getRouteKey(route)" />
  7. </keep-alive>
  8. </RouterTransition>
  9. </router-view>
  10. </template>
  11. <script lang="ts" setup>
  12. import { RouteLocationNormalized, RouteRecordNormalized, RouteRecordName } from 'vue-router'
  13. import animateRouter from '@mobile/router/animateRouter'
  14. import RouterTransition from '@mobile/components/base/router-transition/index.vue'
  15. import http from '@/services/http'
  16. const { state } = animateRouter
  17. // 手动给组件添加 name 属性,处理缓存 exclude 无效的问题
  18. const handleComponent = (component: Record<'type', { name: RouteRecordName | undefined }>, route: RouteRecordNormalized) => {
  19. if (component) {
  20. component.type.name = route.name
  21. }
  22. return component
  23. }
  24. // key 的作用是当 $route.query 参数发生变化时会刷新页面
  25. // 不直接使用 $route.fullPath 的原因是每次都会刷新页面,导致嵌套路由缓存失效
  26. const getRouteKey = (route: RouteLocationNormalized) => {
  27. const qs = Object.keys(route.query)
  28. return qs.length ? route.fullPath : undefined
  29. }
  30. const onLeave = () => {
  31. http.pending = true
  32. }
  33. const onAfterEnter = () => {
  34. http.pending = false
  35. }
  36. </script>
  37. <style lang="less">
  38. @import './index.less';
  39. </style>