@ebiz/designer-components 0.0.18 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/package.json +3 -2
  2. package/src/apiService/mockDataService.js +116 -0
  3. package/src/apiService/simpleDataService.js +186 -80
  4. package/src/components/Button.vue +72 -22
  5. package/src/components/EbizAvatar.vue +116 -0
  6. package/src/components/EbizCheckbox.vue +94 -0
  7. package/src/components/EbizCheckboxGroup.vue +70 -0
  8. package/src/components/EbizDetailBlock.vue +82 -0
  9. package/src/components/EbizDialog.vue +244 -56
  10. package/src/components/EbizEmployeeInfo.vue +139 -0
  11. package/src/components/EbizFileUpload.vue +202 -0
  12. package/src/components/EbizPageHeader.vue +96 -0
  13. package/src/components/EbizPagination.vue +163 -0
  14. package/src/components/EbizRadio.vue +87 -0
  15. package/src/components/EbizRadioGroup.vue +84 -0
  16. package/src/components/EbizRemoteSelect.vue +118 -40
  17. package/src/components/EbizSpace.vue +101 -0
  18. package/src/components/EbizStatistic.vue +150 -0
  19. package/src/components/EbizSwiper.vue +114 -0
  20. package/src/components/EbizSwiperItem.vue +14 -0
  21. package/src/components/EbizSwitch.vue +86 -0
  22. package/src/components/EbizTabHeader.vue +145 -0
  23. package/src/components/EbizTabPanel.vue +23 -0
  24. package/src/components/EbizTable.vue +466 -0
  25. package/src/components/EbizTableColumn.vue +117 -0
  26. package/src/components/EbizTableSort.vue +181 -0
  27. package/src/components/EbizTabs.vue +133 -91
  28. package/src/components/EbizTimePicker.vue +144 -0
  29. package/src/components/EbizTitle.vue +3 -10
  30. package/src/components/EbizTree.vue +153 -0
  31. package/src/components/EbizTreeSelector.vue +423 -0
  32. package/src/components/Home.vue +8 -0
  33. package/src/components/TdesignAlert.vue +116 -0
  34. package/src/components/TdesignButton.vue +130 -0
  35. package/src/components/TdesignCalendar/index.vue +146 -0
  36. package/src/components/TdesignCard.vue +196 -0
  37. package/src/components/TdesignCol.vue +102 -0
  38. package/src/components/TdesignCollapse.vue +143 -0
  39. package/src/components/TdesignCollapsePanel.vue +80 -0
  40. package/src/components/TdesignDatePicker.vue +125 -0
  41. package/src/components/TdesignDialog.vue +226 -0
  42. package/src/components/TdesignForm.vue +134 -0
  43. package/src/components/TdesignFormItem.vue +106 -0
  44. package/src/components/TdesignGrid.vue +56 -0
  45. package/src/components/TdesignIcon.vue +68 -0
  46. package/src/components/TdesignImage.vue +163 -0
  47. package/src/components/TdesignImageViewer.vue +201 -0
  48. package/src/components/TdesignInput.vue +243 -0
  49. package/src/components/TdesignSelect.vue +445 -0
  50. package/src/components/TdesignTag.vue +118 -0
  51. package/src/components/TdesignTextarea.vue +143 -0
  52. package/src/components/TdesignTimeline.vue +58 -0
  53. package/src/components/TdesignTimelineItem.vue +72 -0
  54. package/src/components/TdesignUpload.vue +757 -0
  55. package/src/components/TdesignWatermark.vue +108 -0
  56. package/src/index.js +130 -0
  57. package/src/main.js +20 -4
  58. package/src/router/index.js +244 -5
  59. package/src/views/Button.vue +7 -3
  60. package/src/views/CheckboxDemo.vue +105 -0
  61. package/src/views/DialogDemo.vue +126 -0
  62. package/src/views/EbizAvatar.vue +224 -0
  63. package/src/views/EbizDetailBlockDemo.vue +31 -0
  64. package/src/views/EbizEmployeeInfo.vue +250 -0
  65. package/src/views/EbizRadioDemo.vue +152 -0
  66. package/src/views/EbizSpace.vue +186 -0
  67. package/src/views/EbizSwiper.vue +158 -0
  68. package/src/views/GridDemo.vue +239 -0
  69. package/src/views/Home.vue +63 -2
  70. package/src/views/PageHeaderDemo.vue +105 -0
  71. package/src/views/PaginationDemo.vue +97 -0
  72. package/src/views/RemoteSelect.vue +336 -5
  73. package/src/views/StatisticDemo.vue +191 -0
  74. package/src/views/SwitchDemo.vue +80 -0
  75. package/src/views/TableDemo.vue +335 -0
  76. package/src/views/TableSortDemo.vue +144 -0
  77. package/src/views/TableView.vue +69 -0
  78. package/src/views/TabsDemo.vue +283 -0
  79. package/src/views/TagDemo.vue +102 -0
  80. package/src/views/TdesignAlert.vue +99 -0
  81. package/src/views/TdesignButton.vue +191 -0
  82. package/src/views/TdesignCalendar.vue +95 -0
  83. package/src/views/TdesignCard.vue +297 -0
  84. package/src/views/TdesignCollapse.vue +294 -0
  85. package/src/views/TdesignDatePicker.vue +188 -0
  86. package/src/views/TdesignForm.vue +249 -0
  87. package/src/views/TdesignIcon.vue +204 -0
  88. package/src/views/TdesignImage.vue +216 -0
  89. package/src/views/TdesignImageViewer.vue +199 -0
  90. package/src/views/TdesignInput.vue +253 -0
  91. package/src/views/TdesignSelect.vue +474 -0
  92. package/src/views/TdesignSwiper.vue +158 -0
  93. package/src/views/TextareaDemo.vue +94 -0
  94. package/src/views/TimePickerDemo.vue +147 -0
  95. package/src/views/TimelineDemo.vue +161 -0
  96. package/src/views/TreeDemo.vue +255 -0
  97. package/src/views/TreeSelectorDemo.vue +246 -0
  98. package/src/views/UploadDemo.vue +122 -0
  99. package/src/views/WatermarkDemo.vue +86 -0
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <t-radio-group
3
+ :allowUncheck="allowUncheck"
4
+ :disabled="disabled"
5
+ :name="name"
6
+ :options="options"
7
+ :size="size"
8
+ :value="modelValue"
9
+ :defaultValue="defaultValue"
10
+ :variant="variant"
11
+ @change="handleChange"
12
+ >
13
+ <!-- 默认插槽 -->
14
+ <slot></slot>
15
+ </t-radio-group>
16
+ </template>
17
+
18
+ <script>
19
+ export default {
20
+ name: "EbizRadioGroup"
21
+ }
22
+ </script>
23
+
24
+ <script setup>
25
+ import { defineProps, defineEmits } from 'vue';
26
+ import { RadioGroup as TRadioGroup } from 'tdesign-vue-next';
27
+
28
+ const props = defineProps({
29
+ // 是否允许取消选中
30
+ allowUncheck: {
31
+ type: Boolean,
32
+ default: false
33
+ },
34
+ // 是否禁用组件
35
+ disabled: {
36
+ type: Boolean,
37
+ default: undefined
38
+ },
39
+ // HTML 元素原生属性
40
+ name: {
41
+ type: String,
42
+ default: ''
43
+ },
44
+ // 以配置形式设置子元素
45
+ options: {
46
+ type: Array,
47
+ default: () => []
48
+ },
49
+ // 组件尺寸
50
+ size: {
51
+ type: String,
52
+ default: 'medium',
53
+ validator: (val) => ['small', 'medium', 'large'].includes(val)
54
+ },
55
+ // 选中值 (v-model)
56
+ modelValue: {
57
+ type: [String, Number, Boolean],
58
+ default: undefined
59
+ },
60
+ // 默认选中值
61
+ defaultValue: {
62
+ type: [String, Number, Boolean],
63
+ default: undefined
64
+ },
65
+ // 单选组件按钮形式
66
+ variant: {
67
+ type: String,
68
+ default: 'outline',
69
+ validator: (val) => ['outline', 'primary-filled', 'default-filled'].includes(val)
70
+ }
71
+ });
72
+
73
+ const emit = defineEmits(['change', 'update:modelValue']);
74
+
75
+ // 选中值变化事件
76
+ const handleChange = (value, context) => {
77
+ emit('update:modelValue', value);
78
+ emit('change', value, context);
79
+ };
80
+ </script>
81
+
82
+ <style lang="less" scoped>
83
+ /* 自定义样式 */
84
+ </style>
@@ -1,14 +1,15 @@
1
1
  <template>
2
- <tiny-select v-model="selectedValue" :options="options" :loading="loading" :remote="true"
3
- :remote-method="handleRemoteSearch" :multiple="multiple" :placeholder="placeholder" :clearable="clearable"
4
- :disabled="disabled" @change="handleChange" @focus="handleRemoteSearch">
5
- <template #prefix>
2
+ <t-select ref="selectRef" v-model="selectedValue" :options="options" :loading="loading" :filterable="true"
3
+ @search="handleRemoteSearch" :multiple="multiple" :placeholder="placeholder" :clearable="clearable"
4
+ :disabled="disabled" :size="size" :empty="emptyText" :popupProps="popupProps" @change="handleChange"
5
+ @focus="handleFocus" @blur="handleBlur">
6
+ <template #prefixIcon v-if="$slots.prefix">
6
7
  <slot name="prefix"></slot>
7
8
  </template>
8
- <template #suffix>
9
+ <template #suffixIcon v-if="$slots.suffix">
9
10
  <slot name="suffix"></slot>
10
11
  </template>
11
- </tiny-select>
12
+ </t-select>
12
13
  </template>
13
14
 
14
15
  <script>
@@ -19,8 +20,8 @@ export default {
19
20
 
20
21
  <script setup>
21
22
  import { ref, onMounted, toRefs, computed } from 'vue';
22
- import { Select as TinySelect } from '@opentiny/vue';
23
- import dataService from "../apiService/simpleDataService";
23
+ import { Select as TSelect } from 'tdesign-vue-next';
24
+ import dataService from '../apiService/simpleDataService';
24
25
 
25
26
  const props = defineProps({
26
27
  /**
@@ -30,6 +31,7 @@ const props = defineProps({
30
31
  type: Object,
31
32
  required: true,
32
33
  default: () => ({
34
+ key: null,
33
35
  apiId: null,
34
36
  apiType: ''
35
37
  })
@@ -39,7 +41,9 @@ const props = defineProps({
39
41
  */
40
42
  queryParams: {
41
43
  type: Object,
42
- default: {}
44
+ default: () => ({
45
+ name: ''
46
+ })
43
47
  },
44
48
  /**
45
49
  * 是否多选
@@ -73,21 +77,54 @@ const props = defineProps({
73
77
  * 默认值
74
78
  */
75
79
  modelValue: {
76
- type: [String, Number],
80
+ type: [String, Number, Array],
77
81
  default: ''
78
82
  },
83
+ /**
84
+ * 选项配置
85
+ */
79
86
  optionsConfig: {
80
- labelField: '',//作为label的字段
81
- valueField: ''//作为value的字段
87
+ type: Object,
88
+ default: () => ({
89
+ labelField: '',
90
+ valueField: ''
91
+ })
92
+ },
93
+ /**
94
+ * 组件尺寸
95
+ */
96
+ size: {
97
+ type: String,
98
+ default: 'medium',
99
+ validator: (val) => ['small', 'medium', 'large'].includes(val)
100
+ },
101
+ /**
102
+ * 空数据文本
103
+ */
104
+ emptyText: {
105
+ type: String,
106
+ default: '暂无数据'
107
+ },
108
+ /**
109
+ * 弹出层配置
110
+ */
111
+ popupProps: {
112
+ type: Object,
113
+ default: () => ({})
82
114
  }
83
115
  });
84
116
 
85
117
  const { modelValue, apiConfig, queryParams } = toRefs(props)
86
118
 
87
- const emit = defineEmits(['update:modelValue', 'change']);
119
+ const emit = defineEmits(['update:modelValue', 'change', 'focus', 'blur']);
88
120
 
89
121
  // 选中的值
90
- const selectedValue = computed(() => modelValue.value)
122
+ const selectedValue = computed({
123
+ get: () => modelValue.value,
124
+ set: (val) => {
125
+ emit('update:modelValue', val);
126
+ }
127
+ });
91
128
 
92
129
  // 选项列表
93
130
  const options = ref([]);
@@ -95,34 +132,69 @@ const options = ref([]);
95
132
  // 加载状态
96
133
  const loading = ref(false);
97
134
 
98
- // 远程搜索处理函数
99
- const handleRemoteSearch = async () => {
100
- if (options.value?.length > 0) return
135
+ // 获取select组件实例
136
+ const selectRef = ref(null);
137
+
138
+ // 暴露focus方法
139
+ const focus = () => {
140
+ selectRef.value?.focus();
141
+ };
101
142
 
143
+ defineExpose({
144
+ focus,
145
+ selectRef,
146
+ options
147
+ });
148
+
149
+ // 远程搜索处理函数
150
+ const handleRemoteSearch = async (keyword) => {
102
151
  loading.value = true;
103
- if (apiConfig.value.apiId && apiConfig.value.apiType >= 0) {
104
- try {
105
- const params = {
106
- queryParams: queryParams.value
107
- };
108
- const res = await dataService.fetch(params, { apiId: props.apiConfig.apiId, apiType: 'MULTIPLE_DATA_SEARCH' });
109
- options.value = res.data.map(item => ({
110
- label: item.label || item.name,
111
- value: item.value || item.id
112
- }));
113
- } catch (error) {
114
- console.error('远程搜索失败:', error);
115
- options.value = [];
116
- } finally {
117
- loading.value = false;
118
- }
152
+ try {
153
+ const params = {
154
+ queryParams: {
155
+ ...queryParams.value,
156
+ name: keyword
157
+ }
158
+ };
159
+ const res = await dataService.fetch(params, {
160
+ key: props.apiConfig.key,
161
+ apiId: props.apiConfig.apiId,
162
+ apiType: 'MULTIPLE_DATA_SEARCH'
163
+ });
164
+ const { labelField, valueField } = props.optionsConfig;
165
+
166
+ options.value = res.data.map(item => ({
167
+ ...item,
168
+ label: labelField ? item[labelField] : (item.label || item.name),
169
+ value: valueField ? item[valueField] : (item.value || item.id)
170
+ }));
171
+ } catch (error) {
172
+ console.error('远程搜索失败:', error);
173
+ options.value = [];
174
+ } finally {
175
+ loading.value = false;
119
176
  }
177
+
178
+ };
179
+
180
+ // 处理获取焦点事件
181
+ const handleFocus = (value, context) => {
182
+ emit('focus', value, context);
183
+ // 当选项为空时,初始加载数据
184
+ if (options.value.length === 0) {
185
+ handleRemoteSearch('');
186
+ }
187
+ };
188
+
189
+ // 处理失去焦点事件
190
+ const handleBlur = (value, context) => {
191
+ emit('blur', value, context);
120
192
  };
121
193
 
122
194
  // 值变化处理函数
123
- const handleChange = (value) => {
195
+ const handleChange = (value, context) => {
124
196
  emit('update:modelValue', value);
125
- emit('change', value);
197
+ emit('change', value, context);
126
198
  };
127
199
 
128
200
  // 组件挂载时,如果有默认值则加载对应的选项
@@ -133,10 +205,17 @@ onMounted(async () => {
133
205
  const params = {
134
206
  queryParams: queryParams.value
135
207
  };
136
- const res = await dataService.fetch(params, { apiId: props.apiConfig.apiId, apiType: 'MULTIPLE_DATA_SEARCH' });
208
+ const res = await dataService.fetch(params, {
209
+ key: props.apiConfig.key,
210
+ apiId: props.apiConfig.apiId,
211
+ apiType: 'MULTIPLE_DATA_SEARCH'
212
+ });
213
+ const { labelField, valueField } = props.optionsConfig;
214
+
137
215
  options.value = res.data.map(item => ({
138
- label: item.label || item.name,
139
- value: item.value || item.id
216
+ ...item,
217
+ label: labelField ? item[labelField] : (item.label || item.name),
218
+ value: valueField ? item[valueField] : (item.value || item.id)
140
219
  }));
141
220
  } catch (error) {
142
221
  console.error('加载默认选项失败:', error);
@@ -144,12 +223,11 @@ onMounted(async () => {
144
223
  loading.value = false;
145
224
  }
146
225
  }
147
-
148
226
  });
149
227
  </script>
150
228
 
151
229
  <style scoped>
152
- .tiny-select {
230
+ .t-select {
153
231
  width: 100%;
154
232
  }
155
233
  </style>
@@ -0,0 +1,101 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue';
3
+ import { Space } from 'tdesign-vue-next';
4
+
5
+ /**
6
+ * EbizSpace 间距组件
7
+ * 基于 TDesign Space 组件封装
8
+ * 用于控制相邻组件之间的间距
9
+ */
10
+
11
+ const props = defineProps({
12
+ /**
13
+ * 对齐方式
14
+ * @values start/end/center/baseline
15
+ */
16
+ align: {
17
+ type: String,
18
+ default: '',
19
+ validator: (val) => ['', 'start', 'end', 'center', 'baseline'].includes(val)
20
+ },
21
+ /**
22
+ * 是否自动换行,仅在 horizontal 时有效
23
+ */
24
+ breakLine: {
25
+ type: Boolean,
26
+ default: false
27
+ },
28
+ /**
29
+ * 间距方向
30
+ * @values vertical/horizontal
31
+ */
32
+ direction: {
33
+ type: String,
34
+ default: 'horizontal',
35
+ validator: (val) => ['vertical', 'horizontal'].includes(val)
36
+ },
37
+ /**
38
+ * 分隔符
39
+ */
40
+ separator: {
41
+ type: [String, Object, Function],
42
+ default: ''
43
+ },
44
+ /**
45
+ * 间距大小
46
+ * @values small/medium/large 或具体数值
47
+ */
48
+ size: {
49
+ type: [String, Number, Array],
50
+ default: 'medium',
51
+ validator: (val) => {
52
+ if (typeof val === 'string') {
53
+ return ['small', 'medium', 'large'].includes(val);
54
+ }
55
+ return true;
56
+ }
57
+ }
58
+ });
59
+
60
+ defineEmits([]);
61
+
62
+ const slots = defineSlots();
63
+
64
+ /**
65
+ * 计算尺寸大小
66
+ */
67
+ const sizeMap = {
68
+ small: '8px',
69
+ medium: '16px',
70
+ large: '24px'
71
+ };
72
+
73
+ const computedSize = computed(() => {
74
+ if (Array.isArray(props.size)) {
75
+ return props.size.map(item => {
76
+ if (typeof item === 'string' && sizeMap[item]) {
77
+ return sizeMap[item];
78
+ }
79
+ return item;
80
+ });
81
+ }
82
+
83
+ if (typeof props.size === 'string' && sizeMap[props.size]) {
84
+ return sizeMap[props.size];
85
+ }
86
+
87
+ return props.size;
88
+ });
89
+ </script>
90
+
91
+ <template>
92
+ <Space
93
+ :align="align"
94
+ :breakLine="breakLine"
95
+ :direction="direction"
96
+ :separator="separator"
97
+ :size="computedSize"
98
+ >
99
+ <slot></slot>
100
+ </Space>
101
+ </template>
@@ -0,0 +1,150 @@
1
+ <template>
2
+ <t-statistic
3
+ ref="statisticRef"
4
+ :animation="animation"
5
+ :animation-start="animationStart"
6
+ :color="color"
7
+ :decimalPlaces="decimalPlaces"
8
+ :loading="loading"
9
+ :prefix="prefix"
10
+ :suffix="suffix"
11
+ :title="title"
12
+ :trend="trend"
13
+ :trend-placement="trendPlacement"
14
+ :unit="unit"
15
+ :value="value"
16
+ @click="handleClick"
17
+ >
18
+ <!-- 加载中状态插槽 -->
19
+ <template v-if="$slots.loading" #loading>
20
+ <slot name="loading"></slot>
21
+ </template>
22
+
23
+ <!-- 前缀插槽 -->
24
+ <template v-if="$slots.prefix" #prefix>
25
+ <slot name="prefix"></slot>
26
+ </template>
27
+
28
+ <!-- 后缀插槽 -->
29
+ <template v-if="$slots.suffix" #suffix>
30
+ <slot name="suffix"></slot>
31
+ </template>
32
+
33
+ <!-- 标题插槽 -->
34
+ <template v-if="$slots.title" #title>
35
+ <slot name="title"></slot>
36
+ </template>
37
+
38
+ <!-- 趋势插槽 -->
39
+ <template v-if="$slots.trend" #trend>
40
+ <slot name="trend"></slot>
41
+ </template>
42
+
43
+ <!-- 单位插槽 -->
44
+ <template v-if="$slots.unit" #unit>
45
+ <slot name="unit"></slot>
46
+ </template>
47
+
48
+ <!-- 默认插槽 -->
49
+ <slot></slot>
50
+ </t-statistic>
51
+ </template>
52
+
53
+ <script>
54
+ export default {
55
+ name: "EbizStatistic"
56
+ }
57
+ </script>
58
+
59
+ <script setup>
60
+ import { defineProps, defineEmits, ref, onMounted } from 'vue';
61
+ import { Statistic as TStatistic } from 'tdesign-vue-next';
62
+
63
+ const props = defineProps({
64
+ // 数值动画配置
65
+ animation: {
66
+ type: Object,
67
+ default: () => ({}),
68
+ },
69
+ // 数值动画开始时间,单位:毫秒
70
+ animationStart: {
71
+ type: Boolean,
72
+ default: false,
73
+ },
74
+ // 颜色
75
+ color: {
76
+ type: String,
77
+ default: '',
78
+ },
79
+ // 小数位数
80
+ decimalPlaces: {
81
+ type: Number,
82
+ default: 0,
83
+ },
84
+ // 加载中状态
85
+ loading: {
86
+ type: Boolean,
87
+ default: false,
88
+ },
89
+ // 前缀内容
90
+ prefix: {
91
+ type: [String, Function],
92
+ default: '',
93
+ },
94
+ // 后缀内容
95
+ suffix: {
96
+ type: [String, Function],
97
+ default: '',
98
+ },
99
+ // 数值显示的标题
100
+ title: {
101
+ type: [String, Function],
102
+ default: '',
103
+ },
104
+ // 趋势
105
+ trend: {
106
+ type: String,
107
+ default: '',
108
+ validator: (val) => ['', 'increase', 'decrease'].includes(val)
109
+ },
110
+ // 趋势展示位置
111
+ trendPlacement: {
112
+ type: String,
113
+ default: 'left',
114
+ validator: (val) => ['left', 'right'].includes(val)
115
+ },
116
+ // 单位内容
117
+ unit: {
118
+ type: [String, Function],
119
+ default: '',
120
+ },
121
+ // 数值
122
+ value: {
123
+ type: Number,
124
+ default: 0,
125
+ },
126
+ });
127
+
128
+ const emit = defineEmits(['click']);
129
+
130
+ // 引用实例,用于调用组件的start方法
131
+ const statisticRef = ref(null);
132
+
133
+ // 点击事件
134
+ const handleClick = (e) => {
135
+ emit('click', e);
136
+ };
137
+
138
+ // 暴露start方法,用于手动开始动画
139
+ defineExpose({
140
+ start: () => {
141
+ if (statisticRef.value) {
142
+ statisticRef.value.start();
143
+ }
144
+ }
145
+ });
146
+ </script>
147
+
148
+ <style lang="less" scoped>
149
+ /* 自定义样式 */
150
+ </style>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <div>
3
+ <swiper v-model="innerCurrent" :animation="animation" :autoplay="autoplay" :direction="direction"
4
+ :duration="duration" :height="height" :interval="interval" :loop="loop" :navigation="navigationConfig"
5
+ :stop-on-hover="stopOnHover" :theme="theme" @change="handleChange">
6
+ <slot></slot>
7
+ <template v-if="$slots.navigation" #navigation>
8
+ <slot name="navigation"></slot>
9
+ </template>
10
+ </swiper>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup>
15
+ import { ref, computed, watch } from 'vue';
16
+ import { Swiper } from 'tdesign-vue-next';
17
+
18
+ const props = defineProps({
19
+ // 轮播切换动画效果类型
20
+ animation: {
21
+ type: String,
22
+ default: 'slide',
23
+ validator: (val) => ['slide', 'fade'].includes(val)
24
+ },
25
+ // 是否自动播放
26
+ autoplay: {
27
+ type: Boolean,
28
+ default: true
29
+ },
30
+ // 当前轮播在哪一项(下标)
31
+ current: {
32
+ type: Number,
33
+ default: 0
34
+ },
35
+ // 默认当前轮播在哪一项(下标)
36
+ defaultCurrent: {
37
+ type: Number,
38
+ default: 0
39
+ },
40
+ // 轮播滑动方向
41
+ direction: {
42
+ type: String,
43
+ default: 'horizontal',
44
+ validator: (val) => ['horizontal', 'vertical'].includes(val)
45
+ },
46
+ // 滑动动画时长
47
+ duration: {
48
+ type: Number,
49
+ default: 300
50
+ },
51
+ // 当使用垂直方向滚动时的高度
52
+ height: {
53
+ type: Number,
54
+ default: undefined
55
+ },
56
+ // 轮播间隔时间
57
+ interval: {
58
+ type: Number,
59
+ default: 5000
60
+ },
61
+ // 是否循环播放
62
+ loop: {
63
+ type: Boolean,
64
+ default: true
65
+ },
66
+ // 导航器配置
67
+ navigation: {
68
+ type: Object,
69
+ default: () => ({})
70
+ },
71
+ // 是否悬浮时停止轮播
72
+ stopOnHover: {
73
+ type: Boolean,
74
+ default: true
75
+ },
76
+ // 深色模式和浅色模式
77
+ theme: {
78
+ type: String,
79
+ default: 'light',
80
+ validator: (val) => ['light', 'dark'].includes(val)
81
+ }
82
+ });
83
+
84
+ const emit = defineEmits(['update:current', 'change']);
85
+
86
+ // 内部current值,支持双向绑定
87
+ const innerCurrent = ref(props.current || props.defaultCurrent);
88
+
89
+ // 监听props.current的变化
90
+ watch(() => props.current, (newVal) => {
91
+ if (newVal !== undefined && newVal !== innerCurrent.value) {
92
+ innerCurrent.value = newVal;
93
+ }
94
+ });
95
+
96
+ // 计算导航器配置
97
+ const navigationConfig = computed(() => {
98
+ if (!props.navigation) return undefined;
99
+ return props.navigation;
100
+ });
101
+
102
+ // 变更事件处理
103
+ const handleChange = (index) => {
104
+ innerCurrent.value = index;
105
+ emit('update:current', index);
106
+ emit('change', index);
107
+ };
108
+ </script>
109
+
110
+ <style scoped>
111
+ .ebiz-swiper-wrapper {
112
+ width: 100%;
113
+ }
114
+ </style>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <t-swiper-item>
3
+ <slot></slot>
4
+ </t-swiper-item>
5
+ </template>
6
+
7
+ <script setup>
8
+ import { SwiperItem as TSwiperItem } from 'tdesign-vue-next';
9
+ // 没有需要单独处理的props,直接透传slot到t-swiper-item
10
+ </script>
11
+
12
+ <style scoped>
13
+ /* 自定义样式可以在这里添加 */
14
+ </style>