CommonListPropsEditor.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <div class="common-list-props-editor">
  3. <a-form :labelCol="{ span: 6 }" size="small">
  4. <a-form-item label="显示 Tab">
  5. <a-checkbox v-model:checked="props.props.showTab" :indeterminate="props.props.showTab === undefined" />
  6. </a-form-item>
  7. <a-form-item label="显示搜索">
  8. <a-checkbox v-model:checked="props.props.showSearch" :indeterminate="props.props.showSearch === undefined" />
  9. </a-form-item>
  10. <a-form-item label="显示总数">
  11. <a-checkbox v-model:checked="props.props.showTotal" :indeterminate="props.props.showTotal === undefined" />
  12. </a-form-item>
  13. <a-form-item label="列表项类型">
  14. <ItemTypeEditor v-model="props.props.itemType" />
  15. </a-form-item>
  16. <a-form-item label="详情页">
  17. <LinkPathEditor v-model="(props.props.detailsPage as string)" :noParams="true" />
  18. </a-form-item>
  19. </a-form>
  20. <a-collapse v-model:activeKey="activeKeys" class="props-collapse">
  21. <a-collapse-panel key="tabs" header="子页面 (tabs) 树型结构">
  22. <div v-for="(tab, i) in tabItems" :key="tabKey(tab, i)" class="nested-item tab-item">
  23. <a-collapse>
  24. <a-collapse-panel :key="i" :header="tabHeader(tab)">
  25. <a-form :labelCol="{ span: 4 }" size="small">
  26. <a-form-item label="文本">
  27. <a-input v-model:value="tab.text" />
  28. </a-form-item>
  29. <a-form-item label="类型">
  30. <a-select
  31. v-model:value="tab.type"
  32. style="width: 100%"
  33. :options="tabTypeOptions"
  34. />
  35. </a-form-item>
  36. <a-form-item label="TAB宽度">
  37. <a-input-number
  38. v-model:value="tab.width"
  39. style="width: 100%"
  40. />
  41. </a-form-item>
  42. <a-form-item label="列表详情页">
  43. <LinkPathEditor v-model="tab.detailsPage" />
  44. </a-form-item>
  45. <a-form-item label="显示">
  46. <a-checkbox
  47. v-model:checked="tab.visible"
  48. :indeterminate="tab.visible === undefined"
  49. >
  50. (仅在TAB组件可见时有效)
  51. </a-checkbox>
  52. </a-form-item>
  53. <template v-if="tab.type === 'list'">
  54. <a-form-item label="数据接口">
  55. <DynamicDataEditor v-model="tab.data" />
  56. </a-form-item>
  57. <a-form-item label="下拉选择定义">
  58. <DropdownDefinesEditor v-model="tab.dropdownDefines" />
  59. </a-form-item>
  60. <a-form-item label="数据处理显示">
  61. <DataSolveEditor v-model="tab.dataSolve" />
  62. </a-form-item>
  63. </template>
  64. <template v-else-if="tab.type === 'jump'">
  65. <a-form-item label="跳转URL">
  66. <a-input v-model:value="tab.url" />
  67. </a-form-item>
  68. <a-form-item label="跳转参数">
  69. <KeyValueEditor
  70. v-model="tab.params"
  71. :forceOneLevel="true"
  72. />
  73. </a-form-item>
  74. </template>
  75. <template v-else-if="tab.type === 'nestCategory'">
  76. <a-form-item label="子栏目">
  77. <NestCategoryEditor :categorys="tab.categorys" />
  78. </a-form-item>
  79. </template>
  80. <a-popconfirm
  81. title="确认删除吗?"
  82. @confirm="removeTab(i)"
  83. >
  84. <a-button type="link" danger size="small">删除 Tab</a-button>
  85. </a-popconfirm>
  86. </a-form>
  87. </a-collapse-panel>
  88. </a-collapse>
  89. </div>
  90. <a-button type="dashed" block size="small" @click="addTab">+ 添加 Tab</a-button>
  91. </a-collapse-panel>
  92. </a-collapse>
  93. </div>
  94. </template>
  95. <script setup lang="ts">
  96. import { ref, computed } from 'vue';
  97. import type { IHomeCommonCategoryListDefine, IHomeCommonCategoryListTabItemDefine } from '../../article/data/CommonCategoryDefine';
  98. import KeyValueEditor from '../components/KeyValueEditor.vue';
  99. import DynamicDataEditor from '../components/DynamicDataEditor.vue';
  100. import LinkPathEditor from '../components/LinkPathEditor.vue';
  101. import DataSolveEditor from '../components/DataSolveEditor.vue';
  102. import NestCategoryEditor from '../subpart/NestCategoryEditor.vue';
  103. import ItemTypeEditor from '../components/ItemTypeEditor.vue';
  104. import DropdownDefinesEditor from '../components/DropdownDefinesEditor.vue';
  105. type TabItem = IHomeCommonCategoryListTabItemDefine;
  106. const props = defineProps<{
  107. props: IHomeCommonCategoryListDefine['props'];
  108. }>();
  109. const emit = defineEmits<{
  110. (e: 'update', p: IHomeCommonCategoryListDefine['props']): void;
  111. }>();
  112. const activeKeys = ref<string[]>(['tabs']);
  113. const tabTypeOptions = [
  114. { value: 'list', label: '通用列表' },
  115. { value: 'jump', label: '跳转页面' },
  116. { value: 'nestCategory', label: '子栏目' },
  117. ];
  118. const tabItems = computed(() => (props.props?.tabs || []) as TabItem[]);
  119. function tabKey(tab: TabItem, i: number) {
  120. return `${i}-${tab.text}-${tab.type}`;
  121. }
  122. function tabHeader(tab: TabItem) {
  123. const t = tab.type || '?';
  124. const text = tab.text || '';
  125. return `${text || 'Tab'} (${t})`;
  126. }
  127. function addTab() {
  128. props.props!.tabs = props.props!.tabs || [];
  129. (props.props!.tabs as TabItem[]).push({ text: '新 Tab', type: 'list' });
  130. }
  131. function removeTab(i: number) {
  132. props.props!.tabs?.splice(i, 1);
  133. }
  134. </script>
  135. <style scoped>
  136. .common-list-props-editor {
  137. font-size: 12px;
  138. }
  139. .props-collapse {
  140. margin-top: 8px;
  141. }
  142. .nested-item {
  143. margin-bottom: 12px;
  144. padding: 8px;
  145. background: #fafafa;
  146. border-radius: 4px;
  147. }
  148. .tab-item :deep(.ant-collapse) {
  149. border: none;
  150. background: transparent;
  151. }
  152. .sub-nested {
  153. margin-bottom: 6px;
  154. }
  155. </style>