@ebiz/designer-components 0.0.18-tj.1 → 0.0.19-beta.1

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 (70) hide show
  1. package/dist/designer-components.css +1 -1
  2. package/dist/index.mjs +66100 -52710
  3. package/package.json +1 -1
  4. package/src/apiService/mockDataService.js +116 -0
  5. package/src/apiService/simpleDataService.js +186 -80
  6. package/src/components/Button.vue +72 -22
  7. package/src/components/EbizAvatar.vue +116 -0
  8. package/src/components/EbizCheckbox.vue +94 -0
  9. package/src/components/EbizCheckboxGroup.vue +70 -0
  10. package/src/components/EbizDetailBlock.vue +82 -0
  11. package/src/components/EbizDialog.vue +249 -0
  12. package/src/components/EbizEmployeeInfo.vue +139 -0
  13. package/src/components/EbizPageHeader.vue +96 -0
  14. package/src/components/EbizPagination.vue +163 -0
  15. package/src/components/EbizRadio.vue +87 -0
  16. package/src/components/EbizRadioGroup.vue +84 -0
  17. package/src/components/EbizRemoteSelect.vue +107 -41
  18. package/src/components/EbizStatistic.vue +150 -0
  19. package/src/components/EbizSwiper.vue +3 -3
  20. package/src/components/EbizSwitch.vue +86 -0
  21. package/src/components/EbizTabHeader.vue +6 -10
  22. package/src/components/EbizTabPanel.vue +23 -0
  23. package/src/components/EbizTable.vue +466 -0
  24. package/src/components/EbizTableColumn.vue +117 -0
  25. package/src/components/EbizTableSort.vue +181 -0
  26. package/src/components/EbizTabs.vue +143 -0
  27. package/src/components/EbizTimePicker.vue +144 -0
  28. package/src/components/EbizTitle.vue +36 -37
  29. package/src/components/EbizTree.vue +153 -0
  30. package/src/components/EbizTreeSelector.vue +418 -0
  31. package/src/components/TdesignAlert.vue +116 -0
  32. package/src/components/TdesignCalendar/index.vue +6 -3
  33. package/src/components/TdesignCol.vue +102 -0
  34. package/src/components/TdesignDialog.vue +226 -0
  35. package/src/components/TdesignGrid.vue +56 -0
  36. package/src/components/TdesignInput.vue +23 -23
  37. package/src/components/TdesignTextarea.vue +143 -0
  38. package/src/components/TdesignTimeline.vue +58 -0
  39. package/src/components/TdesignTimelineItem.vue +72 -0
  40. package/src/components/TdesignUpload.vue +757 -0
  41. package/src/components/TdesignWatermark.vue +108 -0
  42. package/src/index.js +85 -0
  43. package/src/main.js +2 -2
  44. package/src/router/index.js +160 -5
  45. package/src/views/Button.vue +7 -3
  46. package/src/views/CheckboxDemo.vue +105 -0
  47. package/src/views/DialogDemo.vue +126 -0
  48. package/src/views/EbizAvatar.vue +224 -0
  49. package/src/views/EbizDetailBlockDemo.vue +31 -0
  50. package/src/views/EbizEmployeeInfo.vue +250 -0
  51. package/src/views/EbizRadioDemo.vue +152 -0
  52. package/src/views/GridDemo.vue +239 -0
  53. package/src/views/Home.vue +49 -2
  54. package/src/views/PageHeaderDemo.vue +105 -0
  55. package/src/views/PaginationDemo.vue +97 -0
  56. package/src/views/RemoteSelect.vue +336 -5
  57. package/src/views/StatisticDemo.vue +191 -0
  58. package/src/views/SwitchDemo.vue +80 -0
  59. package/src/views/TableDemo.vue +335 -0
  60. package/src/views/TableSortDemo.vue +144 -0
  61. package/src/views/TableView.vue +69 -0
  62. package/src/views/TabsDemo.vue +283 -0
  63. package/src/views/TdesignAlert.vue +99 -0
  64. package/src/views/TextareaDemo.vue +94 -0
  65. package/src/views/TimePickerDemo.vue +147 -0
  66. package/src/views/TimelineDemo.vue +161 -0
  67. package/src/views/TreeDemo.vue +255 -0
  68. package/src/views/TreeSelectorDemo.vue +246 -0
  69. package/src/views/UploadDemo.vue +122 -0
  70. package/src/views/WatermarkDemo.vue +86 -0
@@ -0,0 +1,418 @@
1
+ <template>
2
+ <div class="ebiz-tree-selector">
3
+ <div class="selected-items" v-if="modelValue && modelValue.length">
4
+ <div v-for="(item, index) in modelValue" :key="index" class="selected-item">
5
+ <span class="item-text">{{ item.label }}</span>
6
+ <span class="item-remove" @click.stop="removeItem(index)">×</span>
7
+ </div>
8
+ </div>
9
+ <t-button @click="showDialog" variant="text" theme="primary" size="small"> 添加 </t-button>
10
+
11
+ <EbizDialog v-model:visible="dialogVisible" header="选择人员/部门" width="800px" placement="center" confirmBtn="确定"
12
+ cancelBtn="取消" @confirm="handleConfirm" @cancel="handleCancel" @close="handleCancel">
13
+ <div class="selector-container">
14
+ <!-- 左侧选择区域 -->
15
+ <div class="left-panel">
16
+ <!-- 顶部搜索区域 -->
17
+ <div class="search-box">
18
+ <t-input v-model="searchText" placeholder="搜索成员、部门或标签" clearable>
19
+ <template #suffix-icon>
20
+ <t-icon name="search"></t-icon>
21
+ </template>
22
+ </t-input>
23
+ </div>
24
+
25
+ <!-- 选项卡 -->
26
+ <t-tabs v-model="activeTab" class="selector-tabs">
27
+ <t-tab-panel value="organization" label="组织架构" :destroyOnHide="false">
28
+
29
+ </t-tab-panel>
30
+ <!-- <t-tab-panel value="department" label="部门"></t-tab-panel> -->
31
+ <!-- <t-tab-panel value="position" label="岗位"></t-tab-panel> -->
32
+ <t-tab-panel value="employee" label="员工"></t-tab-panel>
33
+ </t-tabs>
34
+
35
+ <!-- 树形结构区域 -->
36
+ <div class="tree-content">
37
+ <div v-if="loading" class="loading-container">
38
+ <t-loading />
39
+ </div>
40
+ <EbizTree ref="organizationTree" v-show="activeTab === 'organization'" checkable :items="organizationData"
41
+ v-model="checkedNodes" v-model:expanded="expandedNodes" :disable-check="disableCheck"
42
+ :keys="{ label: 'name', value: 'id', children: 'childs' }" />
43
+ <!-- <EbizTree
44
+ v-else-if="activeTab === 'department'"
45
+ checkable
46
+ :items="filteredData."
47
+ v-model="checkedNodes"
48
+ :disable-check="disableCheck"
49
+ />
50
+ <EbizTree
51
+ v-else-if="activeTab === 'position'"
52
+ checkable
53
+ :items="filteredData.position"
54
+ v-model="checkedNodes"
55
+ :disable-check="disableCheck"
56
+ /> -->
57
+ <EbizTree ref="employeeTree" v-show="activeTab === 'employee'" checkable :items="employeeData"
58
+ :keys="{ label: 'label', value: 'bindid', children: 'childs' }" v-model="checkedUserNodes"
59
+ :disable-check="disableCheck" />
60
+ </div>
61
+ </div>
62
+
63
+ <!-- 右侧已选区域 -->
64
+ <div class="right-panel">
65
+ <div class="selected-title">已选择的部门、成员</div>
66
+ <div class="selected-count">共 {{ [...selectPreview, ...selectPreviewUser].length }} 项</div>
67
+ <div class="selected-list">
68
+ <div v-for="(item, index) in [...selectPreview,...selectPreviewUser]" :key="index"
69
+ class="selected-list-item">
70
+ <t-icon :name="getIconForType(item)" class="item-icon" />
71
+ <span class="selected-label">{{ item.label }}</span>
72
+ <t-icon name="close-circle" class="remove-icon" @click="removePreviewItem(item)" />
73
+ </div>
74
+ <div v-if="[...selectPreview, ...selectPreviewUser].length === 0" class="no-selection">
75
+ <t-icon name="info-circle" />
76
+ <span style="user-select: none">请在左侧选择部门或成员</span>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </EbizDialog>
82
+ </div>
83
+ </template>
84
+
85
+ <script setup>
86
+ import { onMounted, ref, watch } from 'vue'
87
+ import {
88
+ Button as TButton,
89
+ Icon as TIcon,
90
+ Input as TInput,
91
+ Loading as TLoading,
92
+ TabPanel as TTabPanel,
93
+ Tabs as TTabs
94
+ } from 'tdesign-vue-next'
95
+ import EbizDialog from './TdesignDialog.vue'
96
+ import EbizTree from './EbizTree.vue'
97
+ import dataService from '../apiService/simpleDataService'
98
+
99
+ const props = defineProps({
100
+ // 选中的数据,支持v-model
101
+ modelValue: {
102
+ type: Array,
103
+ default: () => []
104
+ },
105
+ // 树形数据,可以是单个数组或分类对象
106
+ data: {
107
+ type: [Array, Object],
108
+ default: () => []
109
+ },
110
+ // 禁用选择的节点
111
+ disableCheck: {
112
+ type: Function,
113
+ default: null
114
+ },
115
+ // 标题
116
+ title: {
117
+ type: String,
118
+ default: '选择人员/部门'
119
+ }
120
+ })
121
+
122
+ const emit = defineEmits(['update:modelValue', 'change'])
123
+
124
+ // 弹窗显示状态
125
+ const dialogVisible = ref(false)
126
+ // 搜索文本
127
+ const searchText = ref('')
128
+ // 选中的节点
129
+ const checkedNodes = ref([])
130
+ const checkedUserNodes = ref([]);
131
+ // 展开的节点
132
+ const expandedNodes = ref([])
133
+ // 当前活动的选项卡
134
+ const activeTab = ref('organization')
135
+ // 弹窗内预览的选中项
136
+ const selectPreview = ref([])
137
+ const selectPreviewUser = ref([])
138
+ // 加载状态
139
+ const loading = ref(false)
140
+ // API返回的数据
141
+ const organizationData = ref([])
142
+ const employeeData = ref([])
143
+ const organizationTree = ref()
144
+ const employeeTree = ref()
145
+
146
+ // 获取API数据
147
+ const fetchApiData = async () => {
148
+ loading.value = true
149
+ try {
150
+ organizationData.value = await dataService.fetch(
151
+ { keyWord: activeTab.value === 'organization' ? searchText.value : '' },
152
+ {},
153
+ '/appdata/execute/plugin?key=organizational_structure'
154
+ )
155
+ employeeData.value = (await dataService.fetch(
156
+ {keyWord:activeTab.value === 'employee' ? searchText.value : ''},
157
+ {},
158
+ "/appdata/execute/plugin?key=all_active_employesse"
159
+ )).map(i=>({
160
+ label:i.name,
161
+ bindid:i.id,
162
+ type:'employee'
163
+ }))
164
+ } catch (error) {
165
+ } finally {
166
+ loading.value = false
167
+ }
168
+ }
169
+
170
+ // 根据类型获取对应图标
171
+ const getIconForType = (item) => {
172
+ const iconMap = {
173
+ GS: 'internet',
174
+ DEPT: 'folder',
175
+ GW: 'user-list',
176
+ employee: 'user'
177
+ }
178
+ return iconMap[item.type] || 'user'
179
+ }
180
+
181
+ // 显示对话框
182
+ function showDialog() {
183
+ // 获取API数据
184
+ fetchApiData()
185
+ // 重置选中的节点
186
+ checkedNodes.value = props.modelValue.filter(i => i.type !== 'employee').map((item) => item.bindid);
187
+ checkedUserNodes.value = props.modelValue.filter(i => i.type === 'employee').map((item) => item.bindid);
188
+ dialogVisible.value = true
189
+ }
190
+
191
+ // 确认选择
192
+ function handleConfirm() {
193
+ const finalValue = [...selectPreview.value.map((item) => ({
194
+ label: item.label,
195
+ bindid: item.bindid,
196
+ type: item.type
197
+ })), ...selectPreviewUser.value];
198
+ emit(
199
+ 'update:modelValue', finalValue
200
+ )
201
+ emit('change', finalValue)
202
+ dialogVisible.value = false
203
+ }
204
+
205
+ // 取消选择
206
+ function handleCancel() {
207
+ dialogVisible.value = false
208
+ }
209
+
210
+ // 移除已选择预览中的项目
211
+ function removePreviewItem(item) {
212
+ const isUser = item.type == 'employee';
213
+ if(isUser){
214
+ let index = selectPreviewUser.value.findIndex(i=>i.bindid === item.bindid);
215
+ const removedUser = selectPreviewUser.value[index];
216
+ selectPreviewUser.value.splice(index,1);
217
+ checkedUserNodes.value = checkedUserNodes.value.filter((value) => value !== removedUser.bindid)
218
+ return
219
+ }
220
+ let index = selectPreview.value.findIndex(i => i.bindid === item.bindid);
221
+ const removedItem = selectPreview.value[index];
222
+ selectPreview.value.splice(index, 1)
223
+ checkedNodes.value = checkedNodes.value.filter((value) => value !== removedItem.bindid)
224
+ }
225
+
226
+ // 移除选中项
227
+ function removeItem(index) {
228
+ const newValue = [...props.modelValue]
229
+ newValue.splice(index, 1)
230
+ emit('update:modelValue', newValue)
231
+ emit('change', newValue)
232
+ }
233
+
234
+ // 监听选中节点变化,同步到预览
235
+ watch(
236
+ checkedNodes,
237
+ (newValues) => {
238
+ if (!organizationTree.value.treeRef) return
239
+ selectPreview.value = newValues.map(organizationTree.value.treeRef.getItem).map((i) => ({
240
+ label: i?.label,
241
+ type: i?.data?.type || i.type,
242
+ bindid: i?.value
243
+ }))
244
+ },
245
+ { deep: true }
246
+ )
247
+ watch(checkedUserNodes,nVal=>{
248
+ selectPreviewUser.value = employeeData.value.filter(i=>nVal.includes(i.bindid))
249
+ },{deep:true})
250
+ // 监听modelValue变化,同步到选中节点
251
+ watch(
252
+ () => props.modelValue,
253
+ (newValue) => {
254
+ checkedNodes.value = newValue.filter(i=>i.type!=='employee').map((item) => item.bindid);
255
+ checkedUserNodes.value = newValue.filter(i => i.type === 'employee').map((item) => item.bindid);
256
+ console.log(newValue,checkedUserNodes.value,267)
257
+ },
258
+ { deep: true ,immediate:true}
259
+ )
260
+ watch(activeTab,nVal=>{
261
+ searchText.value = ''
262
+ })
263
+ watch(searchText,nVal=>{
264
+ fetchApiData()
265
+ })
266
+ </script>
267
+
268
+ <style scoped>
269
+ .ebiz-tree-selector {
270
+ display: flex;
271
+ flex-wrap: wrap;
272
+ align-items: center;
273
+ gap: 8px;
274
+ min-height: 32px;
275
+ }
276
+
277
+ .selected-items {
278
+ display: flex;
279
+ flex-wrap: wrap;
280
+ gap: 4px;
281
+ }
282
+
283
+ .selected-item {
284
+ display: flex;
285
+ align-items: center;
286
+ padding: 4px 8px;
287
+ background-color: #f0f0f0;
288
+ border-radius: 4px;
289
+ font-size: 14px;
290
+ }
291
+
292
+ .item-text {
293
+ margin-right: 4px;
294
+ }
295
+
296
+ .item-remove {
297
+ cursor: pointer;
298
+ color: #999;
299
+ font-size: 16px;
300
+ }
301
+
302
+ .item-remove:hover {
303
+ color: #ff4d4f;
304
+ }
305
+
306
+ .add-button {
307
+ display: flex;
308
+ align-items: center;
309
+ }
310
+
311
+ .selector-container {
312
+ display: flex;
313
+ height: 500px;
314
+ }
315
+
316
+ .left-panel {
317
+ flex: 1;
318
+ display: flex;
319
+ flex-direction: column;
320
+ border-right: 1px solid #e0e0e0;
321
+ padding-right: 16px;
322
+ }
323
+
324
+ .right-panel {
325
+ width: 280px;
326
+ display: flex;
327
+ flex-direction: column;
328
+ padding-left: 16px;
329
+ }
330
+
331
+ .search-box {
332
+ margin-bottom: 12px;
333
+ }
334
+
335
+ .selector-tabs {
336
+ margin-bottom: 12px;
337
+ }
338
+
339
+ .tree-content {
340
+ flex: 1;
341
+ overflow: auto;
342
+ border: 1px solid #e0e0e0;
343
+ border-radius: 4px;
344
+ padding: 12px;
345
+ position: relative;
346
+ }
347
+
348
+ .loading-container {
349
+ position: absolute;
350
+ top: 0;
351
+ left: 0;
352
+ right: 0;
353
+ bottom: 0;
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: center;
357
+ background-color: rgba(255, 255, 255, 0.7);
358
+ }
359
+
360
+ .selected-title {
361
+ font-weight: bold;
362
+ margin-bottom: 8px;
363
+ }
364
+
365
+ .selected-count {
366
+ color: #999;
367
+ font-size: 12px;
368
+ margin-bottom: 12px;
369
+ }
370
+
371
+ .selected-list {
372
+ flex: 1;
373
+ overflow: auto;
374
+ border: 1px solid #e0e0e0;
375
+ border-radius: 4px;
376
+ padding: 8px;
377
+ }
378
+
379
+ .selected-list-item {
380
+ display: flex;
381
+ align-items: center;
382
+ padding: 8px;
383
+ border-bottom: 1px solid #f0f0f0;
384
+ }
385
+
386
+ .selected-list-item:last-child {
387
+ border-bottom: none;
388
+ }
389
+
390
+ .item-icon {
391
+ color: #0052d9;
392
+ margin-right: 8px;
393
+ }
394
+
395
+ .selected-label {
396
+ flex: 1;
397
+ user-select: none;
398
+ }
399
+
400
+ .remove-icon {
401
+ color: #999;
402
+ cursor: pointer;
403
+ }
404
+
405
+ .remove-icon:hover {
406
+ color: #ff4d4f;
407
+ }
408
+
409
+ .no-selection {
410
+ display: flex;
411
+ flex-direction: column;
412
+ align-items: center;
413
+ justify-content: center;
414
+ height: 100%;
415
+ color: #999;
416
+ gap: 8px;
417
+ }
418
+ </style>
@@ -0,0 +1,116 @@
1
+ <template>
2
+ <t-alert
3
+ :theme="theme"
4
+ :title="title"
5
+ :message="message"
6
+ :icon="icon"
7
+ :close="close"
8
+ :maxLine="maxLine"
9
+ :operation="operation"
10
+ :description="description"
11
+ :close-btn="closeBtn"
12
+ :default-open="defaultOpen"
13
+ @close="handleClose"
14
+ >
15
+ <!-- 标题插槽 -->
16
+ <template v-if="$slots.title" #title>
17
+ <slot name="title"></slot>
18
+ </template>
19
+
20
+ <!-- 内容插槽 -->
21
+ <template v-if="$slots.default">
22
+ <slot></slot>
23
+ </template>
24
+
25
+ <!-- 操作区插槽 -->
26
+ <template v-if="$slots.operation" #operation>
27
+ <slot name="operation"></slot>
28
+ </template>
29
+
30
+ <!-- 关闭按钮插槽 -->
31
+ <template v-if="$slots['close-btn']" #close-btn>
32
+ <slot name="close-btn"></slot>
33
+ </template>
34
+
35
+ <!-- 图标插槽 -->
36
+ <template v-if="$slots.icon" #icon>
37
+ <slot name="icon"></slot>
38
+ </template>
39
+ </t-alert>
40
+ </template>
41
+
42
+ <script>
43
+ export default {
44
+ name: "EbizAlert"
45
+ }
46
+ </script>
47
+
48
+ <script setup>
49
+ import { defineProps, defineEmits } from 'vue';
50
+ import { Alert as TAlert } from 'tdesign-vue-next';
51
+
52
+ const props = defineProps({
53
+ // 主题
54
+ theme: {
55
+ type: String,
56
+ default: 'info',
57
+ validator: (val) => ['success', 'info', 'warning', 'error'].includes(val)
58
+ },
59
+ // 标题
60
+ title: {
61
+ type: String,
62
+ default: ''
63
+ },
64
+ // 内容
65
+ message: {
66
+ type: String,
67
+ default: ''
68
+ },
69
+ // 图标
70
+ icon: {
71
+ type: [Boolean, Function],
72
+ default: true
73
+ },
74
+ // 关闭按钮
75
+ close: {
76
+ type: Boolean,
77
+ default: false
78
+ },
79
+ // 内容显示最大行数
80
+ maxLine: {
81
+ type: Number,
82
+ default: 0
83
+ },
84
+ // 操作区内容
85
+ operation: {
86
+ type: [String, Function],
87
+ default: ''
88
+ },
89
+ // 描述内容
90
+ description: {
91
+ type: String,
92
+ default: ''
93
+ },
94
+ // 关闭按钮内容
95
+ closeBtn: {
96
+ type: [String, Function, Boolean],
97
+ default: undefined
98
+ },
99
+ // 默认是否显示打开
100
+ defaultOpen: {
101
+ type: Boolean,
102
+ default: true
103
+ }
104
+ });
105
+
106
+ const emit = defineEmits(['close']);
107
+
108
+ // 关闭事件
109
+ const handleClose = (e) => {
110
+ emit('close', e);
111
+ };
112
+ </script>
113
+
114
+ <style lang="less" scoped>
115
+ /* 自定义样式 */
116
+ </style>
@@ -14,7 +14,7 @@
14
14
  :month-change="monthChange"
15
15
  :render-cell="renderCell"
16
16
  :theme="theme"
17
- :value="value"
17
+ :value="modelValue"
18
18
  :year="year"
19
19
  @cell-click="handleCellClick"
20
20
  @cell-double-click="handleCellDoubleClick"
@@ -111,7 +111,7 @@ export default {
111
111
  default: 'full',
112
112
  validator: (val) => ['full', 'card'].includes(val)
113
113
  },
114
- value: {
114
+ modelValue: {
115
115
  type: [String, Number, Array, Date],
116
116
  default: null
117
117
  },
@@ -120,10 +120,13 @@ export default {
120
120
  default: undefined
121
121
  }
122
122
  },
123
- emits: ['cell-click', 'cell-double-click', 'cell-right-click', 'month-change'],
123
+ emits: ['cell-click', 'cell-double-click', 'cell-right-click', 'month-change', 'update:modelValue'],
124
124
  methods: {
125
125
  handleCellClick(options) {
126
126
  this.$emit('cell-click', options)
127
+ if (options && options.date) {
128
+ this.$emit('update:modelValue', options.date)
129
+ }
127
130
  },
128
131
  handleCellDoubleClick(options) {
129
132
  this.$emit('cell-double-click', options)
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <t-col
3
+ :span="span"
4
+ :order="order"
5
+ :offset="offset"
6
+ :push="push"
7
+ :pull="pull"
8
+ :flex="flex"
9
+ :xs="xs"
10
+ :sm="sm"
11
+ :md="md"
12
+ :lg="lg"
13
+ :xl="xl"
14
+ :xxl="xxl"
15
+ :tag="tag"
16
+ >
17
+ <slot></slot>
18
+ </t-col>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ name: "EbizCol"
24
+ }
25
+ </script>
26
+
27
+ <script setup>
28
+ import { defineProps } from 'vue';
29
+ import { Col as TCol } from 'tdesign-vue-next';
30
+
31
+ defineProps({
32
+ // 栅格占位格数,0-24之间的数值
33
+ span: {
34
+ type: [String, Number],
35
+ default: undefined
36
+ },
37
+ // 栅格顺序,用于在flex布局下调整顺序
38
+ order: {
39
+ type: [String, Number],
40
+ default: undefined
41
+ },
42
+ // 栅格左侧的间隔格数,间隔内不可以有栅格
43
+ offset: {
44
+ type: [String, Number],
45
+ default: undefined
46
+ },
47
+ // 栅格向右移动格数
48
+ push: {
49
+ type: [String, Number],
50
+ default: undefined
51
+ },
52
+ // 栅格向左移动格数
53
+ pull: {
54
+ type: [String, Number],
55
+ default: undefined
56
+ },
57
+ // flex 布局属性
58
+ flex: {
59
+ type: [String, Number],
60
+ default: undefined
61
+ },
62
+ // <768px 响应式栅格,可为栅格数或一个包含栅格参数的对象
63
+ xs: {
64
+ type: [String, Number, Object],
65
+ default: undefined
66
+ },
67
+ // ≥768px 响应式栅格,可为栅格数或一个包含栅格参数的对象
68
+ sm: {
69
+ type: [String, Number, Object],
70
+ default: undefined
71
+ },
72
+ // ≥992px 响应式栅格,可为栅格数或一个包含栅格参数的对象
73
+ md: {
74
+ type: [String, Number, Object],
75
+ default: undefined
76
+ },
77
+ // ≥1200px 响应式栅格,可为栅格数或一个包含栅格参数的对象
78
+ lg: {
79
+ type: [String, Number, Object],
80
+ default: undefined
81
+ },
82
+ // ≥1400px 响应式栅格,可为栅格数或一个包含栅格参数的对象
83
+ xl: {
84
+ type: [String, Number, Object],
85
+ default: undefined
86
+ },
87
+ // ≥1880px 响应式栅格,可为栅格数或一个包含栅格参数的对象
88
+ xxl: {
89
+ type: [String, Number, Object],
90
+ default: undefined
91
+ },
92
+ // 自定义元素标签
93
+ tag: {
94
+ type: String,
95
+ default: 'div'
96
+ }
97
+ });
98
+ </script>
99
+
100
+ <style lang="less" scoped>
101
+ /* 自定义样式 */
102
+ </style>