index.vue 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <template>
  2. <div class="agreement">
  3. <van-nav-bar fixed :title="title" left-arrow @click-left="onClickLeft" placeholder />
  4. <div class="agreementContent">
  5. <component :is="currentComponent" />
  6. </div>
  7. </div>
  8. </template>
  9. <script setup lang="ts">
  10. import { onBeforeMount, shallowRef, ref } from 'vue'
  11. import { useRoute } from 'vue-router'
  12. type AgreementType = 'auth' | 'privacy'
  13. const route = useRoute()
  14. const title = ref('协议')
  15. const currentComponent = shallowRef<any>(null) // ✅ 关键:用 shallowRef 存放组件,避免被代理
  16. // 动态组件映射
  17. const componentsMap: Record<
  18. AgreementType,
  19. { title: string; loader: () => Promise<{ default: any }> }
  20. > = {
  21. auth: { title: '授权协议', loader: () => import('./components/AuthAgreement.vue') },
  22. privacy: { title: '隐私权政策', loader: () => import('./components/PrivacyAgreement.vue') },
  23. }
  24. onBeforeMount(async () => {
  25. // 读取 ?type=auth|privacy,兜底为 auth
  26. const rawType = (route.query.type as string) || 'auth'
  27. const type = (['auth', 'privacy'].includes(rawType) ? rawType : 'auth') as AgreementType
  28. const match = componentsMap[type]
  29. try {
  30. const mod = await match.loader()
  31. currentComponent.value = mod.default // ✅ shallowRef 不会触发“组件被做成响应式”的告警
  32. } catch (e) {
  33. console.log('err', e)
  34. // 兜底:加载失败时给出一个简单占位组件
  35. currentComponent.value = {
  36. name: 'LoadFailed',
  37. template: `<div style="color:#f56c6c;">协议内容加载失败,请稍后重试。</div>`,
  38. }
  39. }
  40. title.value = match.title
  41. document.title = match.title
  42. })
  43. const onClickLeft = () => history.back()
  44. </script>
  45. <style lang="scss" scoped>
  46. .van-nav-bar {
  47. background-color: #fff;
  48. border-bottom: 1px solid #f2f2f2;
  49. font-weight: 600;
  50. }
  51. /* 修改左侧返回图标颜色与大小 */
  52. ::v-deep(.van-icon-arrow-left) {
  53. color: #ff8036;
  54. font-size: 20px;
  55. }
  56. .agreementContent {
  57. padding: 16px;
  58. overflow-y: auto;
  59. }
  60. </style>