@vela-studio/ui 1.0.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 (68) hide show
  1. package/README.md +152 -0
  2. package/dist/index.d.ts +696 -0
  3. package/dist/index.js +10 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +11786 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/dist/index.umd.js +10 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/style.css +1 -0
  10. package/index.ts +150 -0
  11. package/package.json +73 -0
  12. package/src/components/advanced/scripting/Scripting.vue +189 -0
  13. package/src/components/advanced/state/State.vue +231 -0
  14. package/src/components/advanced/trigger/Trigger.vue +256 -0
  15. package/src/components/basic/button/Button.vue +120 -0
  16. package/src/components/basic/container/Container.vue +22 -0
  17. package/src/components/chart/barChart/barChart.vue +176 -0
  18. package/src/components/chart/doughnutChart/doughnutChart.vue +128 -0
  19. package/src/components/chart/funnelChart/funnelChart.vue +128 -0
  20. package/src/components/chart/gaugeChart/gaugeChart.vue +144 -0
  21. package/src/components/chart/lineChart/lineChart.vue +188 -0
  22. package/src/components/chart/pieChart/pieChart.vue +114 -0
  23. package/src/components/chart/radarChart/radarChart.vue +115 -0
  24. package/src/components/chart/sankeyChart/sankeyChart.vue +144 -0
  25. package/src/components/chart/scatterChart/scatterChart.vue +162 -0
  26. package/src/components/chart/stackedBarChart/stackedBarChart.vue +184 -0
  27. package/src/components/content/html/Html.vue +104 -0
  28. package/src/components/content/iframe/Iframe.vue +111 -0
  29. package/src/components/content/markdown/Markdown.vue +174 -0
  30. package/src/components/controls/breadcrumb/Breadcrumb.vue +79 -0
  31. package/src/components/controls/buttonGroup/ButtonGroup.vue +93 -0
  32. package/src/components/controls/checkboxGroup/CheckboxGroup.vue +147 -0
  33. package/src/components/controls/dateRange/DateRange.vue +174 -0
  34. package/src/components/controls/multiSelect/MultiSelect.vue +155 -0
  35. package/src/components/controls/navButton/NavButton.vue +97 -0
  36. package/src/components/controls/pagination/Pagination.vue +94 -0
  37. package/src/components/controls/searchBox/SearchBox.vue +170 -0
  38. package/src/components/controls/select/Select.vue +134 -0
  39. package/src/components/controls/slider/Slider.vue +167 -0
  40. package/src/components/controls/switch/Switch.vue +107 -0
  41. package/src/components/data/cardGrid/CardGrid.vue +318 -0
  42. package/src/components/data/list/List.vue +282 -0
  43. package/src/components/data/pivot/Pivot.vue +270 -0
  44. package/src/components/data/table/Table.vue +150 -0
  45. package/src/components/data/timeline/Timeline.vue +315 -0
  46. package/src/components/group/Group.vue +75 -0
  47. package/src/components/kpi/box/Box.vue +98 -0
  48. package/src/components/kpi/countUp/CountUp.vue +193 -0
  49. package/src/components/kpi/progress/Progress.vue +159 -0
  50. package/src/components/kpi/stat/Stat.vue +205 -0
  51. package/src/components/kpi/text/Text.vue +74 -0
  52. package/src/components/layout/badge/Badge.vue +105 -0
  53. package/src/components/layout/col/Col.vue +114 -0
  54. package/src/components/layout/flex/Flex.vue +105 -0
  55. package/src/components/layout/grid/Grid.vue +89 -0
  56. package/src/components/layout/modal/Modal.vue +118 -0
  57. package/src/components/layout/panel/Panel.vue +162 -0
  58. package/src/components/layout/row/Row.vue +99 -0
  59. package/src/components/layout/tabs/Tabs.vue +117 -0
  60. package/src/components/media/image/Image.vue +132 -0
  61. package/src/components/media/video/Video.vue +115 -0
  62. package/src/components/v2/basic/BaseButton.vue +179 -0
  63. package/src/components/v2/kpi/KpiCard.vue +215 -0
  64. package/src/components/v2/layout/GridBox.vue +55 -0
  65. package/src/hooks/useDataSource.ts +123 -0
  66. package/src/types/gis.ts +251 -0
  67. package/src/utils/chartUtils.ts +349 -0
  68. package/src/utils/dataUtils.ts +403 -0
@@ -0,0 +1,159 @@
1
+ <template>
2
+ <div class="v-progress-container" :style="containerStyle">
3
+ <el-progress
4
+ :percentage="percentage"
5
+ :type="type"
6
+ :status="status"
7
+ :stroke-width="strokeWidth"
8
+ :text-inside="textInside"
9
+ :show-text="showText"
10
+ :color="computedColor"
11
+ :format="formatText"
12
+ :width="circleWidth"
13
+ :stroke-linecap="strokeLinecap"
14
+ :striped="showStripe"
15
+ :striped-flow="animateStripe"
16
+ class="custom-progress"
17
+ />
18
+ </div>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { computed } from 'vue'
23
+ import type { CSSProperties } from 'vue'
24
+ import { ElProgress } from 'element-plus'
25
+
26
+ // 颜色配置类型
27
+ interface ColorStop {
28
+ color: string
29
+ percentage: number
30
+ }
31
+
32
+ // 定义纯 UI Props,无业务逻辑
33
+ const props = withDefaults(
34
+ defineProps<{
35
+ // 核心数据
36
+ percentage?: number
37
+ type?: 'line' | 'circle' | 'dashboard'
38
+ status?: '' | 'success' | 'exception' | 'warning'
39
+
40
+ // 进度条配置
41
+ strokeWidth?: number
42
+ textInside?: boolean
43
+ showText?: boolean
44
+ showStripe?: boolean
45
+ animateStripe?: boolean
46
+ circleWidth?: number
47
+ strokeLinecap?: 'butt' | 'round' | 'square'
48
+ textFormat?: string
49
+
50
+ // 颜色配置
51
+ barColor?: string
52
+ trackColor?: string
53
+ textColor?: string
54
+ successColor?: string
55
+ warningColor?: string
56
+ exceptionColor?: string
57
+ useGradient?: boolean
58
+
59
+ // 容器样式
60
+ opacity?: number
61
+ visible?: boolean
62
+ backgroundColor?: string
63
+ borderColor?: string
64
+ borderWidth?: number
65
+ borderRadius?: number
66
+ padding?: number
67
+ }>(),
68
+ {
69
+ percentage: 0,
70
+ type: 'line',
71
+ status: '',
72
+ strokeWidth: 6,
73
+ textInside: false,
74
+ showText: true,
75
+ showStripe: false,
76
+ animateStripe: false,
77
+ circleWidth: 126,
78
+ strokeLinecap: 'round',
79
+ textFormat: '{value}%',
80
+ opacity: 100,
81
+ visible: true,
82
+ backgroundColor: 'transparent',
83
+ borderColor: 'transparent',
84
+ borderWidth: 0,
85
+ borderRadius: 0,
86
+ padding: 10,
87
+ barColor: '#409eff',
88
+ trackColor: '#e4e7ed',
89
+ textColor: '#606266',
90
+ },
91
+ )
92
+
93
+ // 计算颜色
94
+ const computedColor = computed<string | ColorStop[]>(() => {
95
+ const barColor = props.barColor
96
+ const successColor = props.successColor ?? '#67c23a'
97
+ const warningColor = props.warningColor ?? '#e6a23c'
98
+ const exceptionColor = props.exceptionColor ?? '#f56c6c'
99
+
100
+ // 根据状态返回对应颜色
101
+ if (props.status) {
102
+ if (props.status === 'success') return successColor
103
+ if (props.status === 'warning') return warningColor
104
+ if (props.status === 'exception') return exceptionColor
105
+ }
106
+
107
+ // 使用渐变色
108
+ if (props.useGradient) {
109
+ return [
110
+ { color: exceptionColor, percentage: 20 },
111
+ { color: warningColor, percentage: 50 },
112
+ { color: successColor, percentage: 100 },
113
+ ]
114
+ }
115
+
116
+ return barColor
117
+ })
118
+
119
+ // 格式化文本
120
+ const formatText = (percentage: number) => {
121
+ const format = props.textFormat
122
+ return format.replace('{value}', percentage.toFixed(0))
123
+ }
124
+
125
+ // 容器样式
126
+ const containerStyle = computed<CSSProperties>(() => {
127
+ return {
128
+ opacity: props.opacity / 100,
129
+ display: props.visible === false ? 'none' : 'flex',
130
+ backgroundColor: props.backgroundColor,
131
+ borderColor: props.borderColor,
132
+ borderWidth: `${props.borderWidth}px`,
133
+ borderStyle: 'solid',
134
+ borderRadius: `${props.borderRadius}px`,
135
+ padding: `${props.padding}px`,
136
+ width: '100%',
137
+ height: '100%',
138
+ alignItems: 'center',
139
+ justifyContent: 'center',
140
+ boxSizing: 'border-box',
141
+ '--el-fill-color-light': props.trackColor, // Hack: Element Plus track color
142
+ } as CSSProperties
143
+ })
144
+ </script>
145
+
146
+ <style scoped>
147
+ .v-progress-container {
148
+ box-sizing: border-box;
149
+ }
150
+
151
+ :deep(.el-progress) {
152
+ width: 100%;
153
+ }
154
+
155
+ :deep(.el-progress__text) {
156
+ font-size: inherit !important;
157
+ color: v-bind('props.textColor');
158
+ }
159
+ </style>
@@ -0,0 +1,205 @@
1
+ <template>
2
+ <div class="v-stat-card" :style="cardStyle">
3
+ <div class="v-stat-header">
4
+ <div class="v-stat-title" :style="titleStyleComputed">{{ title }}</div>
5
+ </div>
6
+ <div class="v-stat-body">
7
+ <div v-if="icon" class="v-stat-icon" :style="iconStyle">
8
+ <i :class="icon"></i>
9
+ </div>
10
+ <div class="v-stat-value" :style="valueStyleComputed">{{ formattedValue }}{{ suffix }}</div>
11
+ </div>
12
+ <div v-if="showChange && (change ?? 0) !== 0" class="v-stat-footer">
13
+ <span class="v-stat-change" :style="changeStyleComputed">
14
+ {{ (change ?? 0) > 0 ? '+' : '' }}{{ (change ?? 0).toFixed(1) }}%
15
+ </span>
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup lang="ts">
21
+ import { computed } from 'vue'
22
+ import type { CSSProperties } from 'vue'
23
+
24
+ // 定义纯 UI Props,无业务逻辑
25
+ const props = withDefaults(
26
+ defineProps<{
27
+ // 数据
28
+ title?: string
29
+ value?: number
30
+ change?: number
31
+ suffix?: string
32
+ icon?: string
33
+ precision?: number
34
+ showChange?: boolean
35
+
36
+ // 卡片样式
37
+ opacity?: number
38
+ visible?: boolean
39
+ backgroundColor?: string
40
+ borderColor?: string
41
+ borderWidth?: number
42
+ borderRadius?: number
43
+ boxShadow?: string
44
+ padding?: number
45
+
46
+ // 标题样式
47
+ titleColor?: string
48
+ titleFontSize?: number
49
+ titleFontWeight?: 'normal' | 'bold' | 'lighter' | number
50
+
51
+ // 数值样式
52
+ valueColor?: string
53
+ valueFontSize?: number
54
+ valueFontWeight?: 'normal' | 'bold' | 'lighter' | number
55
+
56
+ // 变化率样式
57
+ changeFontSize?: number
58
+ changeFontWeight?: 'normal' | 'bold' | 'lighter' | number
59
+ changeColorPositive?: string
60
+ changeColorNegative?: string
61
+
62
+ // 图标样式
63
+ iconColor?: string
64
+ iconSize?: number
65
+ }>(),
66
+ {
67
+ title: 'Statistic Title',
68
+ value: 0,
69
+ change: 0,
70
+ suffix: '',
71
+ icon: '',
72
+ precision: 0,
73
+ showChange: false,
74
+ opacity: 100,
75
+ visible: true,
76
+ backgroundColor: '#fff',
77
+ borderColor: '#e0e0e0',
78
+ borderWidth: 1,
79
+ borderRadius: 8,
80
+ boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
81
+ padding: 20,
82
+ titleColor: '#909399',
83
+ titleFontSize: 14,
84
+ titleFontWeight: 'normal',
85
+ valueColor: '#303133',
86
+ valueFontSize: 24,
87
+ valueFontWeight: 'bold',
88
+ changeFontSize: 14,
89
+ changeFontWeight: 500,
90
+ changeColorPositive: '#28a745',
91
+ changeColorNegative: '#dc3545',
92
+ iconColor: '#409eff',
93
+ iconSize: 32,
94
+ },
95
+ )
96
+
97
+ // 格式化显示值
98
+ const formattedValue = computed(() => {
99
+ const val = props.value
100
+ const prec = props.precision
101
+ return val.toLocaleString(undefined, {
102
+ minimumFractionDigits: prec,
103
+ maximumFractionDigits: prec,
104
+ })
105
+ })
106
+
107
+ // 卡片样式
108
+ const cardStyle = computed<CSSProperties>(() => {
109
+ return {
110
+ opacity: props.opacity / 100,
111
+ display: props.visible === false ? 'none' : 'flex',
112
+ backgroundColor: props.backgroundColor,
113
+ borderColor: props.borderColor,
114
+ borderWidth: `${props.borderWidth}px`,
115
+ borderStyle: 'solid',
116
+ borderRadius: `${props.borderRadius}px`,
117
+ boxShadow: props.boxShadow,
118
+ padding: `${props.padding}px`,
119
+ flexDirection: 'column',
120
+ justifyContent: 'space-between',
121
+ width: '100%',
122
+ height: '100%',
123
+ boxSizing: 'border-box',
124
+ }
125
+ })
126
+
127
+ // 标题样式
128
+ const titleStyleComputed = computed<CSSProperties>(() => {
129
+ return {
130
+ color: props.titleColor,
131
+ fontSize: `${props.titleFontSize}px`,
132
+ fontWeight: props.titleFontWeight,
133
+ margin: 0,
134
+ }
135
+ })
136
+
137
+ // 数值样式
138
+ const valueStyleComputed = computed<CSSProperties>(() => {
139
+ return {
140
+ color: props.valueColor,
141
+ fontSize: `${props.valueFontSize}px`,
142
+ fontWeight: props.valueFontWeight,
143
+ lineHeight: 1,
144
+ }
145
+ })
146
+
147
+ // 变化率样式
148
+ const changeStyleComputed = computed<CSSProperties>(() => {
149
+ const changeVal = props.change
150
+ const color = changeVal > 0 ? props.changeColorPositive : props.changeColorNegative
151
+ return {
152
+ color,
153
+ fontSize: `${props.changeFontSize}px`,
154
+ fontWeight: props.changeFontWeight,
155
+ }
156
+ })
157
+
158
+ // 图标样式
159
+ const iconStyle = computed<CSSProperties>(() => {
160
+ return {
161
+ fontSize: `${props.iconSize}px`,
162
+ color: props.iconColor,
163
+ }
164
+ })
165
+ </script>
166
+
167
+ <style scoped>
168
+ .v-stat-card {
169
+ box-sizing: border-box;
170
+ }
171
+
172
+ .v-stat-header {
173
+ margin-bottom: 8px;
174
+ }
175
+
176
+ .v-stat-title {
177
+ font-size: 14px;
178
+ color: #909399;
179
+ margin: 0;
180
+ }
181
+
182
+ .v-stat-body {
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 12px;
186
+ flex: 1;
187
+ }
188
+
189
+ .v-stat-icon {
190
+ display: flex;
191
+ align-items: center;
192
+ }
193
+
194
+ .v-stat-value {
195
+ line-height: 1;
196
+ }
197
+
198
+ .v-stat-footer {
199
+ margin-top: 8px;
200
+ }
201
+
202
+ .v-stat-change {
203
+ font-weight: 500;
204
+ }
205
+ </style>
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <div class="v-text" :style="textStyle">
3
+ {{ content }}
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import type { CSSProperties } from 'vue'
10
+
11
+ // 定义纯 UI Props,无业务逻辑
12
+ const props = withDefaults(
13
+ defineProps<{
14
+ // 内容
15
+ content?: string
16
+
17
+ // 样式配置
18
+ fontSize?: number | string // 标准化类型
19
+ color?: string // 标准化命名:原 fontColor
20
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number | string
21
+ textAlign?: 'left' | 'center' | 'right' | 'justify'
22
+ letterSpacing?: number | string
23
+ lineHeight?: number | string
24
+ paddingX?: number
25
+ paddingY?: number
26
+ opacity?: number
27
+ visible?: boolean
28
+ locked?: boolean
29
+ }>(),
30
+ {
31
+ content: '文本内容',
32
+ fontSize: 16,
33
+ color: '#000000',
34
+ fontWeight: 'normal',
35
+ textAlign: 'left',
36
+ letterSpacing: 0,
37
+ lineHeight: 1.2,
38
+ paddingX: 0,
39
+ paddingY: 0,
40
+ opacity: 100,
41
+ visible: true,
42
+ locked: false,
43
+ },
44
+ )
45
+
46
+ // 计算文本样式
47
+ const textStyle = computed<CSSProperties>(() => {
48
+ return {
49
+ opacity: props.opacity / 100,
50
+ display: props.visible === false ? 'none' : 'block',
51
+ fontSize: typeof props.fontSize === 'number' ? `${props.fontSize}px` : props.fontSize,
52
+ color: props.color,
53
+ fontWeight: props.fontWeight,
54
+ textAlign: props.textAlign,
55
+ letterSpacing:
56
+ typeof props.letterSpacing === 'number' ? `${props.letterSpacing}px` : props.letterSpacing,
57
+ lineHeight: props.lineHeight,
58
+ padding: `${props.paddingY}px ${props.paddingX}px`,
59
+ width: '100%',
60
+ height: '100%',
61
+ userSelect: props.locked ? 'none' : 'text',
62
+ pointerEvents: props.locked ? 'none' : 'auto',
63
+ overflow: 'hidden',
64
+ boxSizing: 'border-box',
65
+ }
66
+ })
67
+ </script>
68
+
69
+ <style scoped>
70
+ .v-text {
71
+ word-break: break-word;
72
+ white-space: pre-wrap;
73
+ }
74
+ </style>
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <div class="v-badge-container" :style="containerStyle">
3
+ <el-badge
4
+ :value="value"
5
+ :type="type"
6
+ :is-dot="isDot"
7
+ :max="max"
8
+ :hidden="hidden"
9
+ :show-zero="showZero"
10
+ :offset="offset"
11
+ >
12
+ <slot>
13
+ <span :style="slotContentStyle">{{ slotText || 'Badge Content' }}</span>
14
+ </slot>
15
+ </el-badge>
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed } from 'vue'
21
+ import type { CSSProperties } from 'vue'
22
+ import { ElBadge } from 'element-plus'
23
+
24
+ // 定义纯 UI Props,无业务逻辑
25
+ const props = withDefaults(
26
+ defineProps<{
27
+ // Badge 值
28
+ value?: string | number
29
+ type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
30
+ isDot?: boolean
31
+ max?: number
32
+ hidden?: boolean
33
+ showZero?: boolean
34
+ offset?: [number, number]
35
+
36
+ // 默认插槽文本(当没有子组件时显示)
37
+ slotText?: string
38
+
39
+ // 容器样式
40
+ opacity?: number
41
+ visible?: boolean
42
+ padding?: number
43
+
44
+ // 插槽内容样式
45
+ slotFontSize?: number
46
+ slotColor?: string
47
+ slotPadding?: number
48
+ }>(),
49
+ {
50
+ value: '1',
51
+ type: 'primary',
52
+ isDot: false,
53
+ max: 99,
54
+ hidden: false,
55
+ showZero: false,
56
+ slotText: '徽章内容',
57
+ opacity: 100,
58
+ visible: true,
59
+ padding: 4,
60
+ slotFontSize: 14,
61
+ slotColor: '#303133',
62
+ slotPadding: 8,
63
+ },
64
+ )
65
+
66
+ // 容器样式
67
+ const containerStyle = computed<CSSProperties>(() => {
68
+ return {
69
+ opacity: props.opacity / 100,
70
+ display: props.visible === false ? 'none' : 'inline-flex',
71
+ padding: `${props.padding}px`,
72
+ boxSizing: 'border-box',
73
+ alignItems: 'center',
74
+ justifyContent: 'center',
75
+ }
76
+ })
77
+
78
+ // 插槽内容样式
79
+ const slotContentStyle = computed<CSSProperties>(() => {
80
+ return {
81
+ fontSize: `${props.slotFontSize}px`,
82
+ color: props.slotColor,
83
+ padding: `${props.slotPadding}px`,
84
+ }
85
+ })
86
+ </script>
87
+
88
+ <style scoped>
89
+ .v-badge-container {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ box-sizing: border-box;
94
+ }
95
+
96
+ :deep(.el-badge) {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ }
101
+
102
+ :deep(.el-badge__content) {
103
+ font-size: inherit !important;
104
+ }
105
+ </style>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <el-col
3
+ :span="span"
4
+ :offset="offset"
5
+ :push="push"
6
+ :pull="pull"
7
+ :xs="xs"
8
+ :sm="sm"
9
+ :md="md"
10
+ :lg="lg"
11
+ :xl="xl"
12
+ :tag="tag"
13
+ :style="containerStyle"
14
+ class="v-col"
15
+ >
16
+ <slot>
17
+ <div class="v-col-placeholder" :style="placeholderStyle">
18
+ {{ placeholder }}
19
+ </div>
20
+ </slot>
21
+ </el-col>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { computed } from 'vue'
26
+ import type { CSSProperties } from 'vue'
27
+ import { ElCol } from 'element-plus'
28
+
29
+ // 响应式尺寸类型
30
+ type ResponsiveSize = number | { span?: number; offset?: number; push?: number; pull?: number }
31
+
32
+ // 定义纯 UI Props
33
+ const props = withDefaults(
34
+ defineProps<{
35
+ // Col 布局属性
36
+ span?: number
37
+ offset?: number
38
+ push?: number
39
+ pull?: number
40
+ xs?: ResponsiveSize
41
+ sm?: ResponsiveSize
42
+ md?: ResponsiveSize
43
+ lg?: ResponsiveSize
44
+ xl?: ResponsiveSize
45
+ tag?: string
46
+
47
+ // 容器样式
48
+ padding?: number
49
+ backgroundColor?: string
50
+ borderRadius?: number
51
+ borderWidth?: number
52
+ borderColor?: string
53
+ minHeight?: string
54
+
55
+ // 占位文本
56
+ placeholder?: string
57
+ textColor?: string
58
+ fontSize?: number
59
+ }>(),
60
+ {
61
+ span: 24,
62
+ offset: 0,
63
+ push: 0,
64
+ pull: 0,
65
+ tag: 'div',
66
+ padding: 0,
67
+ backgroundColor: 'transparent',
68
+ borderRadius: 0,
69
+ borderWidth: 0,
70
+ borderColor: '#dcdfe6',
71
+ minHeight: 'auto',
72
+ placeholder: '列布局容器 - 可拖入其他组件',
73
+ textColor: '#909399',
74
+ fontSize: 14,
75
+ },
76
+ )
77
+
78
+ // 容器样式
79
+ const containerStyle = computed<CSSProperties>(() => {
80
+ return {
81
+ padding: `${props.padding}px`,
82
+ backgroundColor: props.backgroundColor,
83
+ borderRadius: `${props.borderRadius}px`,
84
+ borderWidth: `${props.borderWidth}px`,
85
+ borderStyle: props.borderWidth ? 'solid' : 'none',
86
+ borderColor: props.borderColor,
87
+ minHeight: props.minHeight,
88
+ boxSizing: 'border-box',
89
+ }
90
+ })
91
+
92
+ // 占位样式
93
+ const placeholderStyle = computed<CSSProperties>(() => {
94
+ return {
95
+ width: '100%',
96
+ minHeight: '50px',
97
+ display: 'flex',
98
+ alignItems: 'center',
99
+ justifyContent: 'center',
100
+ color: props.textColor,
101
+ fontSize: `${props.fontSize}px`,
102
+ }
103
+ })
104
+ </script>
105
+
106
+ <style scoped>
107
+ .v-col {
108
+ box-sizing: border-box;
109
+ }
110
+
111
+ .v-col-placeholder {
112
+ width: 100%;
113
+ }
114
+ </style>