LinkPathEditor.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <template>
  2. <a-form-item class="link-path-editor" label="跳转路径">
  3. <a-collapse v-model:activeKey="activeKey" ghost>
  4. <a-collapse-panel key="1" header="设置">
  5. <a-form-item>
  6. <div class="path-selector">
  7. <a-select
  8. v-model:value="pathType"
  9. style="width: 150px; margin-right: 8px"
  10. @change="handlePathTypeChange"
  11. >
  12. <a-select-option value="dynamic-list">动态页面列表</a-select-option>
  13. <a-select-option value="internal">程序内置页面</a-select-option>
  14. <a-select-option value="custom">自定义输入</a-select-option>
  15. </a-select>
  16. <!-- 动态页面地址 -->
  17. <a-select
  18. v-if="pathType === 'dynamic-list'"
  19. v-model:value="localPageConfigName"
  20. style="flex: 1"
  21. @change="updateLink"
  22. placeholder="请选择动态页面"
  23. >
  24. <a-select-option
  25. v-for="page in pageList"
  26. :key="page.name"
  27. :value="page.name"
  28. >
  29. {{ page.title }} ({{ page.name }})
  30. </a-select-option>
  31. </a-select>
  32. <!-- 程序内置页面 -->
  33. <a-select
  34. v-else-if="pathType === 'internal'"
  35. v-model:value="linkPath"
  36. style="flex: 1"
  37. @change="updateLink"
  38. placeholder="请选择内置页面"
  39. >
  40. <a-select-option
  41. v-for="page in internalPages"
  42. :key="page.path"
  43. :value="page.path"
  44. >
  45. {{ page.path }}
  46. </a-select-option>
  47. </a-select>
  48. <!-- 自定义输入 -->
  49. <a-input
  50. v-else-if="pathType === 'custom'"
  51. v-model:value="linkPath"
  52. placeholder="请输入跳转路径"
  53. @change="updateLink"
  54. style="flex: 1"
  55. />
  56. </div>
  57. </a-form-item>
  58. <a-form-item v-if="pathType !== 'dynamic-list'" label="参数设置">
  59. <KeyValueEditor
  60. v-model="localParams"
  61. :forceOneLevel="true"
  62. :defaultCreateTemplate="{ key: '', value: '', type: 'string' }"
  63. />
  64. </a-form-item>
  65. </a-collapse-panel>
  66. </a-collapse>
  67. </a-form-item>
  68. </template>
  69. <script setup lang="ts">
  70. import { inject, ref, watch, computed } from 'vue';
  71. import KeyValueEditor from './KeyValueEditor.vue';
  72. import type { IHomeCommonCategoryDefine } from '@/pages/article/data/CommonCategoryDefine';
  73. import PagesJson from '@/pages.json';
  74. import { CommonCategoryListPath } from '@/pages/article/data/CommonCategoryPathDefine';
  75. // 定义props
  76. const props = defineProps<{
  77. modelValue?: string|[string, object]|undefined;
  78. }>();
  79. const emit = defineEmits<{
  80. (e: 'update:modelValue', value: [string, object]): void;
  81. }>();
  82. const pageList = inject<(IHomeCommonCategoryDefine['page'][0])[]>('pageList', []);
  83. const activeKey = ref('');
  84. // 跳转路径类型
  85. const pathType = ref<'dynamic-list' | 'internal' | 'custom'>('custom');
  86. // 跳转路径
  87. const linkPath = ref('');
  88. const localPageConfigName = ref('');
  89. const localParams = ref<Record<string, string>>({});
  90. // 从PagesJson中提取内置页面
  91. const internalPages = computed(() => {
  92. if (!PagesJson || !PagesJson.pages) {
  93. return [];
  94. }
  95. return PagesJson.pages.map((page: any) => ({
  96. path: "/" + page.path
  97. }));
  98. });
  99. // 监听参数变化
  100. watch(
  101. () => props.modelValue,
  102. (newValue) => {
  103. if (Array.isArray(newValue)) {
  104. linkPath.value = newValue[0] || '';
  105. localParams.value = newValue[1] as Record<string, string> || {};
  106. } else {
  107. linkPath.value = newValue || '';
  108. localParams.value = {};
  109. }
  110. if (linkPath.value == CommonCategoryListPath) {
  111. pathType.value = 'dynamic-list';
  112. localPageConfigName.value = localParams.value.pageConfigName || '';
  113. } else if (linkPath.value.startsWith('/pages/')) {
  114. pathType.value = 'internal';
  115. } else {
  116. pathType.value = 'custom';
  117. }
  118. },
  119. { deep: true, immediate: true }
  120. );
  121. watch(
  122. localParams,
  123. () => {
  124. updateLink();
  125. },
  126. { deep: true }
  127. );
  128. // 处理路径类型变化
  129. const handlePathTypeChange = () => {
  130. updateLink();
  131. };
  132. // 更新链接
  133. const updateLink = () => {
  134. if (pathType.value === 'dynamic-list') {
  135. localParams.value = {
  136. pageConfigName: localPageConfigName.value || '',
  137. };
  138. linkPath.value = CommonCategoryListPath;
  139. }
  140. emit('update:modelValue', [
  141. linkPath.value,
  142. localParams.value,
  143. ]);
  144. };
  145. </script>
  146. <style lang="scss" scoped>
  147. .link-path-editor {
  148. ::v-deep .ant-collapse-header {
  149. padding: 0 !important;
  150. }
  151. .path-selector {
  152. display: flex;
  153. align-items: center;
  154. }
  155. }
  156. </style>