@mc-markets/ui 1.0.63 → 1.0.67

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 (102) hide show
  1. package/dist/components/Alert/Alert.vue.d.ts +8 -0
  2. package/dist/components/Alert/Alert.vue.d.ts.map +1 -0
  3. package/dist/components/Banner/Banner.vue.d.ts +38 -0
  4. package/dist/components/Banner/Banner.vue.d.ts.map +1 -0
  5. package/dist/components/Button/Button.vue.d.ts +8 -0
  6. package/dist/components/Button/Button.vue.d.ts.map +1 -0
  7. package/dist/components/Card/Card.vue.d.ts +8 -0
  8. package/dist/components/Card/Card.vue.d.ts.map +1 -0
  9. package/dist/components/DatePicker/DatePicker.vue.d.ts +13 -0
  10. package/dist/components/DatePicker/DatePicker.vue.d.ts.map +1 -0
  11. package/dist/components/Dialog/Dialog.vue.d.ts +30 -0
  12. package/dist/components/Dialog/Dialog.vue.d.ts.map +1 -0
  13. package/dist/components/Empty/Empty.vue.d.ts +11 -0
  14. package/dist/components/Empty/Empty.vue.d.ts.map +1 -0
  15. package/dist/components/Form/Form.vue.d.ts +8 -0
  16. package/dist/components/Form/Form.vue.d.ts.map +1 -0
  17. package/dist/components/FormItem/FormItem.vue.d.ts +8 -0
  18. package/dist/components/FormItem/FormItem.vue.d.ts.map +1 -0
  19. package/dist/components/Icon/Icon.vue.d.ts +30 -0
  20. package/dist/components/Icon/Icon.vue.d.ts.map +1 -0
  21. package/dist/components/Input/Input.vue.d.ts +8 -0
  22. package/dist/components/Input/Input.vue.d.ts.map +1 -0
  23. package/dist/components/Notification/Notification.vue.d.ts +8 -0
  24. package/dist/components/Notification/Notification.vue.d.ts.map +1 -0
  25. package/dist/components/Option/Option.vue.d.ts +8 -0
  26. package/dist/components/Option/Option.vue.d.ts.map +1 -0
  27. package/dist/components/OptionGroup/OptionGroup.vue.d.ts +8 -0
  28. package/dist/components/OptionGroup/OptionGroup.vue.d.ts.map +1 -0
  29. package/dist/components/Pagination/Pagination.vue.d.ts +8 -0
  30. package/dist/components/Pagination/Pagination.vue.d.ts.map +1 -0
  31. package/dist/components/Radio/Radio.vue.d.ts +13 -0
  32. package/dist/components/Radio/Radio.vue.d.ts.map +1 -0
  33. package/dist/components/RadioButton/RadioButton.vue.d.ts +13 -0
  34. package/dist/components/RadioButton/RadioButton.vue.d.ts.map +1 -0
  35. package/dist/components/RadioGroup/RadioGroup.vue.d.ts +13 -0
  36. package/dist/components/RadioGroup/RadioGroup.vue.d.ts.map +1 -0
  37. package/dist/components/Select/Select.vue.d.ts +8 -0
  38. package/dist/components/Select/Select.vue.d.ts.map +1 -0
  39. package/dist/components/Switch/Switch.vue.d.ts +13 -0
  40. package/dist/components/Switch/Switch.vue.d.ts.map +1 -0
  41. package/dist/components/Table/Table.vue.d.ts +8 -0
  42. package/dist/components/Table/Table.vue.d.ts.map +1 -0
  43. package/dist/components/Table/TableColumn.vue.d.ts +8 -0
  44. package/dist/components/Table/TableColumn.vue.d.ts.map +1 -0
  45. package/dist/components/Tabs/TabPane.vue.d.ts +23 -0
  46. package/dist/components/Tabs/TabPane.vue.d.ts.map +1 -0
  47. package/dist/components/Tabs/Tabs.vue.d.ts +31 -0
  48. package/dist/components/Tabs/Tabs.vue.d.ts.map +1 -0
  49. package/dist/components/Tag/Tag.vue.d.ts +8 -0
  50. package/dist/components/Tag/Tag.vue.d.ts.map +1 -0
  51. package/dist/components/Tooltip/Tooltip.vue.d.ts +13 -0
  52. package/dist/components/Tooltip/Tooltip.vue.d.ts.map +1 -0
  53. package/dist/hooks/useClassName.d.ts +8 -0
  54. package/dist/hooks/useClassName.d.ts.map +1 -0
  55. package/dist/index.cjs +2 -0
  56. package/dist/index.cjs.map +1 -0
  57. package/dist/index.d.ts +76 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.mjs +1136 -0
  60. package/dist/index.mjs.map +1 -0
  61. package/dist/style.css +1 -0
  62. package/dist/styles/font/iconfont.d.ts +1 -0
  63. package/dist/styles/font/iconfont.d.ts.map +1 -0
  64. package/dist/utils/classNames.d.ts +3 -0
  65. package/dist/utils/classNames.d.ts.map +1 -0
  66. package/dist/utils/styleUtils.d.ts +31 -0
  67. package/dist/utils/styleUtils.d.ts.map +1 -0
  68. package/package.json +19 -18
  69. package/packages/components/Alert/Alert.vue +13 -0
  70. package/packages/components/Banner/Banner.vue +299 -0
  71. package/packages/components/Button/Button.vue +18 -0
  72. package/packages/components/Card/Card.vue +20 -0
  73. package/packages/components/DatePicker/DatePicker.vue +71 -0
  74. package/packages/components/Dialog/Dialog.vue +102 -0
  75. package/packages/components/Empty/Empty.vue +74 -0
  76. package/packages/components/Form/Form.vue +17 -0
  77. package/packages/components/FormItem/FormItem.vue +20 -0
  78. package/packages/components/Icon/Icon.vue +210 -0
  79. package/packages/components/Input/Input.vue +25 -0
  80. package/packages/components/Notification/Notification.vue +13 -0
  81. package/packages/components/Option/Option.vue +13 -0
  82. package/packages/components/OptionGroup/OptionGroup.vue +13 -0
  83. package/packages/components/Pagination/Pagination.vue +23 -0
  84. package/packages/components/Radio/Radio.vue +130 -0
  85. package/packages/components/RadioButton/RadioButton.vue +110 -0
  86. package/packages/components/RadioGroup/RadioGroup.vue +155 -0
  87. package/packages/components/Select/Select.vue +22 -0
  88. package/packages/components/Switch/Switch.vue +134 -0
  89. package/packages/components/Table/Table.vue +17 -0
  90. package/packages/components/Table/TableColumn.vue +20 -0
  91. package/packages/components/Tabs/TabPane.vue +98 -0
  92. package/packages/components/Tabs/Tabs.vue +414 -0
  93. package/packages/components/Tag/Tag.vue +61 -0
  94. package/packages/components/Tooltip/Tooltip.vue +58 -0
  95. package/packages/hooks/useClassName.js +23 -0
  96. package/packages/styles/README.md +129 -0
  97. package/packages/styles/components/override.scss +234 -0
  98. package/packages/styles/index.scss +76 -124
  99. package/packages/utils/classNames.js +23 -0
  100. package/packages/utils/styleUtils.js +105 -0
  101. package/dist/index.js +0 -19254
  102. package/dist/index.js.css +0 -1
@@ -0,0 +1,299 @@
1
+ <template>
2
+ <div
3
+ v-if="visible"
4
+ class="m-banner"
5
+ :class="[
6
+ `m-banner--${type}`,
7
+ {
8
+ 'm-banner--closable': closable,
9
+ 'm-banner--with-icon': icon || slots.icon
10
+ }
11
+ ]"
12
+ :style="bannerStyle"
13
+ >
14
+ <div class="m-banner__content">
15
+ <!-- 图标插槽 -->
16
+ <div v-if="icon || slots.icon" class="m-banner__icon">
17
+ <slot name="icon">
18
+ <m-icon :name="icon" :size="iconSize" />
19
+ </slot>
20
+ </div>
21
+
22
+ <!-- 主要内容 -->
23
+ <div class="m-banner__text">
24
+ <slot>{{ content }}</slot>
25
+ </div>
26
+
27
+ <!-- 关闭按钮 -->
28
+ <div v-if="closable" class="m-banner__close" @click="handleClose">
29
+ <m-icon name="lucide-x" :size="closeIconSize" />
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </template>
34
+
35
+ <script setup>
36
+ import { ref, computed, watch, useSlots } from 'vue'
37
+ import MIcon from '../Icon/Icon.vue'
38
+
39
+ // 获取插槽
40
+ const slots = useSlots()
41
+
42
+ // 定义 props
43
+ const props = defineProps({
44
+ // 横幅内容
45
+ content: {
46
+ type: String,
47
+ default: ''
48
+ },
49
+ // 横幅类型
50
+ type: {
51
+ type: String,
52
+ default: 'info',
53
+ validator: (value) => ['info', 'success', 'warning', 'error'].includes(value)
54
+ },
55
+ // 是否可关闭
56
+ closable: {
57
+ type: Boolean,
58
+ default: true
59
+ },
60
+ // 是否显示
61
+ visible: {
62
+ type: Boolean,
63
+ default: true
64
+ },
65
+ // 图标名称
66
+ icon: {
67
+ type: String,
68
+ default: ''
69
+ },
70
+ // 图标大小
71
+ iconSize: {
72
+ type: [String, Number],
73
+ default: '16px'
74
+ },
75
+ // 关闭图标大小
76
+ closeIconSize: {
77
+ type: [String, Number],
78
+ default: '16px'
79
+ },
80
+ // 自定义背景色
81
+ backgroundColor: {
82
+ type: String,
83
+ default: ''
84
+ },
85
+ // 自定义文字颜色
86
+ textColor: {
87
+ type: String,
88
+ default: ''
89
+ },
90
+ // 自定义边框颜色
91
+ borderColor: {
92
+ type: String,
93
+ default: ''
94
+ },
95
+ // 持续时间(毫秒),0 表示不自动关闭
96
+ duration: {
97
+ type: Number,
98
+ default: 0
99
+ }
100
+ })
101
+
102
+ // 定义 emits
103
+ const emit = defineEmits(['close', 'update:visible'])
104
+
105
+ // 响应式数据
106
+ const internalVisible = ref(props.visible)
107
+
108
+ // 监听 visible prop 变化
109
+ watch(() => props.visible, (newVal) => {
110
+ internalVisible.value = newVal
111
+ })
112
+
113
+ // 计算样式
114
+ const bannerStyle = computed(() => {
115
+ const style = {}
116
+
117
+ if (props.backgroundColor) {
118
+ style.backgroundColor = props.backgroundColor
119
+ }
120
+ if (props.textColor) {
121
+ style.color = props.textColor
122
+ }
123
+ if (props.borderColor) {
124
+ style.borderColor = props.borderColor
125
+ }
126
+
127
+ return style
128
+ })
129
+
130
+ // 默认图标映射
131
+ const defaultIcons = {
132
+ info: 'info',
133
+ success: 'check-circle',
134
+ warning: 'warning',
135
+ error: 'close-circle'
136
+ }
137
+
138
+ // 计算实际使用的图标
139
+ const actualIcon = computed(() => {
140
+ return props.icon || defaultIcons[props.type]
141
+ })
142
+
143
+ // 处理关闭
144
+ const handleClose = () => {
145
+ internalVisible.value = false
146
+ emit('update:visible', false)
147
+ emit('close')
148
+ }
149
+
150
+ // 自动关闭逻辑
151
+ watch(internalVisible, (newVal) => {
152
+ if (newVal && props.duration > 0) {
153
+ setTimeout(() => {
154
+ handleClose()
155
+ }, props.duration)
156
+ }
157
+ })
158
+
159
+ // 定义组件名称
160
+ defineOptions({
161
+ name: 'MBanner'
162
+ })
163
+
164
+ // 暴露方法给父组件
165
+ defineExpose({
166
+ close: handleClose
167
+ })
168
+ </script>
169
+
170
+ <style scoped lang="scss">
171
+ .m-banner {
172
+ position: relative;
173
+ display: flex;
174
+ align-items: center;
175
+ min-height: 40px;
176
+ border-radius: 4px;
177
+ border: 1px solid;
178
+ font-size: 14px;
179
+ line-height: 1.5;
180
+ padding: 10px;
181
+ transition: all 0.3s ease;
182
+
183
+ &__content {
184
+ display: flex;
185
+ align-items: center;
186
+ width: 100%;
187
+ flex: 1;
188
+ }
189
+
190
+ &__icon {
191
+ display: flex;
192
+ align-items: center;
193
+ margin-right: 8px;
194
+ flex-shrink: 0;
195
+ }
196
+
197
+ &__text {
198
+ flex: 1;
199
+ word-break: break-word;
200
+ }
201
+
202
+ &__close {
203
+ display: flex;
204
+ align-items: center;
205
+ justify-content: center;
206
+ margin-left: 8px;
207
+ cursor: pointer;
208
+ padding: 4px;
209
+ border-radius: 3px;
210
+ transition: background-color 0.2s ease;
211
+ flex-shrink: 0;
212
+ min-width: 20px;
213
+ min-height: 20px;
214
+ opacity: 0.7;
215
+
216
+ &:hover {
217
+ background-color: rgba(0, 0, 0, 0.1);
218
+ opacity: 1;
219
+ }
220
+ }
221
+
222
+ // 类型样式
223
+ &--info {
224
+ background-color: #e1f3ff;
225
+ border-color: #b3d8ff;
226
+ color: #0066cc;
227
+
228
+ .m-banner__close:hover {
229
+ background-color: rgba(0, 102, 204, 0.1);
230
+ }
231
+ }
232
+
233
+ &--success {
234
+ background-color: #f0f9ff;
235
+ border-color: #b3e5b3;
236
+ color: #00a854;
237
+
238
+ .m-banner__close:hover {
239
+ background-color: rgba(0, 168, 84, 0.1);
240
+ }
241
+ }
242
+
243
+ &--warning {
244
+ background-color: #fff7e6;
245
+ border-color: #ffd591;
246
+ color: #fa8c16;
247
+
248
+ .m-banner__close:hover {
249
+ background-color: rgba(250, 140, 22, 0.1);
250
+ }
251
+ }
252
+
253
+ &--error {
254
+ background-color: #fff2f0;
255
+ border-color: #ffccc7;
256
+ color: #ff4d4f;
257
+
258
+ .m-banner__close:hover {
259
+ background-color: rgba(255, 77, 79, 0.1);
260
+ }
261
+ }
262
+
263
+ // 带动画的关闭
264
+ &.m-banner-leave-active {
265
+ opacity: 0;
266
+ transform: translateY(-10px);
267
+ transition: opacity 0.3s ease, transform 0.3s ease;
268
+ }
269
+ }
270
+
271
+ // 深色主题适配
272
+ @media (prefers-color-scheme: dark) {
273
+ .m-banner {
274
+ &--info {
275
+ background-color: rgba(24, 144, 255, 0.1);
276
+ border-color: rgba(24, 144, 255, 0.3);
277
+ color: #69c0ff;
278
+ }
279
+
280
+ &--success {
281
+ background-color: rgba(82, 196, 26, 0.1);
282
+ border-color: rgba(82, 196, 26, 0.3);
283
+ color: #95de64;
284
+ }
285
+
286
+ &--warning {
287
+ background-color: rgba(250, 173, 20, 0.1);
288
+ border-color: rgba(250, 173, 20, 0.3);
289
+ color: #ffd666;
290
+ }
291
+
292
+ &--error {
293
+ background-color: rgba(255, 77, 79, 0.1);
294
+ border-color: rgba(255, 77, 79, 0.3);
295
+ color: #ff7875;
296
+ }
297
+ }
298
+ }
299
+ </style>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <el-button v-bind="$attrs" class="m-button">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-button>
7
+ </template>
8
+
9
+ <script setup>
10
+ defineOptions({
11
+ name: 'MButton'
12
+ })
13
+ </script>
14
+
15
+ <style lang="scss" scoped>
16
+ // Button 组件样式 - 使用高优先级选择器确保不被全局样式覆盖
17
+
18
+ </style>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <el-card v-bind="$attrs" class="m-card">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-card>
7
+ </template>
8
+
9
+ <script setup>
10
+ defineOptions({
11
+ name: 'MCard'
12
+ })
13
+ </script>
14
+
15
+ <style lang="scss">
16
+ // Card 组件样式 - 使用 m-card 类名隔离样式
17
+ .m-card {
18
+ // 自定义样式可以在这里添加
19
+ }
20
+ </style>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <el-date-picker v-bind="mergedAttrs" :popper-class="popperClass">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-date-picker>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { useClassName } from "@packages/hooks/useClassName.js";
11
+
12
+ defineOptions({
13
+ name: "MDatePicker",
14
+ });
15
+
16
+ // 定义 props,提供默认的 type 值
17
+ const props = defineProps({
18
+ popperClass: {
19
+ type: String,
20
+ default: "",
21
+ },
22
+ });
23
+
24
+ // 使用类名 Hook,排除 type 和 popperClass 属性
25
+ const { mergedAttrs, className: popperClass } = useClassName(
26
+ "mc-datepicker-popper",
27
+ "popperClass"
28
+ );
29
+ </script>
30
+ <style lang="scss">
31
+ .mc-datepicker-popper {
32
+ .el-picker-panel {
33
+ border: 1px solid var(--border-primary);
34
+ border-radius: 6px;
35
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
36
+ .current,
37
+ .today:not(.in-range),
38
+ .start-date,
39
+ .end-date {
40
+ .el-date-table-cell {
41
+ .el-date-table-cell__text {
42
+ color: var(--text-quaternary);
43
+ border-radius: 3px;
44
+ }
45
+ }
46
+ }
47
+
48
+ .start-date {
49
+ .el-date-table-cell {
50
+ border-top-left-radius: 3px;
51
+ border-bottom-left-radius: 3px;
52
+ }
53
+ }
54
+
55
+ .end-date {
56
+ .el-date-table-cell {
57
+ border-top-right-radius: 3px;
58
+ border-bottom-right-radius: 3px;
59
+ }
60
+ }
61
+
62
+ .el-button.is-text {
63
+ color: var(--text-brand);
64
+ }
65
+ .el-button.is-plain {
66
+ background: var(--bg-brand);
67
+ color: var(--text-quaternary);
68
+ }
69
+ }
70
+ }
71
+ </style>
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <div>
3
+ <el-dialog
4
+ v-model="dialogVisible"
5
+ :width="width"
6
+ :title="title"
7
+ :draggable="draggable"
8
+ :close-on-click-modal="closeOnClickModal"
9
+ :center="center"
10
+ v-bind="$attrs"
11
+ class="m-dialog"
12
+ header-class="m-header"
13
+ >测试组
14
+ <template v-if="$slots.header" #header="{ close, titleId, titleClass }">
15
+ <slot name="header" v-bind="{ close, titleId, titleClass }"></slot>
16
+ </template>
17
+ <slot name="default"></slot>
18
+ <template v-if="$slots.footer" #footer class="m-footer">
19
+ <slot name="footer"></slot>
20
+ </template>
21
+ </el-dialog>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ const props = defineProps({
27
+ width: {
28
+ type: String,
29
+ default: '440px'
30
+ },
31
+ center: {
32
+ type: Boolean,
33
+ default: true
34
+ },
35
+ draggable: {
36
+ type: Boolean,
37
+ default: true
38
+ },
39
+ closeOnClickModal: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ title: {
44
+ type: String,
45
+ default: ''
46
+ }
47
+ })
48
+ const emit = defineEmits(['close'])
49
+ const dialogVisible = defineModel('modelValue', {
50
+ type: Boolean,
51
+ default: false
52
+ })
53
+
54
+ </script>
55
+
56
+ <style scoped lang="scss">
57
+ :deep(.m-dialog) {
58
+ --el-dialog-padding-primary:24px;
59
+ --el-dialog-title-font-size:24px;
60
+ --el-dialog-border-radius:16px;
61
+ --el-dialog-bg-color:var(--bg-tertiary);
62
+ }
63
+
64
+ :deep(.m-header) {
65
+ padding-bottom: 24px;
66
+ padding-right: 0;
67
+
68
+ .el-dialog__title {
69
+ line-height: 32px;
70
+ font-weight: 600;
71
+ color: var(--text-primary);
72
+ }
73
+
74
+ .el-dialog__headerbtn {
75
+ width: 24px;
76
+ height: 24px;
77
+ right: 22px;
78
+ top: 22px;
79
+ display: flex;
80
+ justify-content: center;
81
+ align-items: center;
82
+
83
+ .el-dialog__close {
84
+ font-size: 20px;
85
+ color: var(--icon-tertiary);
86
+ }
87
+
88
+ &:hover{
89
+ .el-dialog__close{
90
+ color: var(--bg-brand-hover);
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ :deep(.el-dialog__footer) {
97
+ display: flex;
98
+ >.el-button{
99
+ flex: 1;
100
+ }
101
+ }
102
+ </style>
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <el-empty v-bind="mergedAttrs" :image="imageUrl">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-empty>
7
+ </template>
8
+
9
+ <script>
10
+ // 定义可选的图片文件名(在模块作用域中)
11
+ const availableImages = [
12
+ '404',
13
+ 'billing',
14
+ 'cart',
15
+ 'comments',
16
+ 'dashboard',
17
+ 'files',
18
+ 'inbox',
19
+ 'location',
20
+ 'network',
21
+ 'notifications',
22
+ 'orders',
23
+ 'records',
24
+ 'session',
25
+ 'subscription',
26
+ 'todo',
27
+ 'wishlist'
28
+ ]
29
+
30
+ export default {
31
+ name: 'MEmpty'
32
+ }
33
+ </script>
34
+
35
+ <script setup>
36
+ import { computed, useAttrs } from 'vue'
37
+
38
+ const props = defineProps({
39
+ image: {
40
+ type: String,
41
+ default: 'orders',
42
+ validator: (value) => {
43
+ // 如果是完整的URL或路径,直接通过验证
44
+ if (value.includes('/') || value.includes('http')) {
45
+ return true
46
+ }
47
+ // 否则检查是否在可选列表中
48
+ return availableImages.includes(value)
49
+ }
50
+ }
51
+ })
52
+
53
+ const attrs = useAttrs()
54
+
55
+ // 排除 image 属性,避免重复绑定
56
+ const mergedAttrs = computed(() => {
57
+ const { image, ...rest } = attrs
58
+ return rest
59
+ })
60
+
61
+ // 计算图片URL
62
+ const imageUrl = computed(() => {
63
+ const { image } = props
64
+
65
+ // 如果是完整的URL或路径,直接返回
66
+ if (image.includes('/') || image.includes('http')) {
67
+ return image
68
+ }
69
+
70
+ // 使用 public 目录中的图片
71
+ // Vite 会自动处理 public 目录中的静态资源
72
+ return `/images/empty/${image}.png`
73
+ })
74
+ </script>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <el-form v-bind="$attrs" class="m-form">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-form>
7
+ </template>
8
+
9
+ <script setup>
10
+ defineOptions({
11
+ name: 'MForm'
12
+ })
13
+ </script>
14
+
15
+ <style lang="scss">
16
+
17
+ </style>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <el-form-item v-bind="$attrs" class="m-form-item">
3
+ <template v-for="(_, name) in $slots" :key="name" #[name]>
4
+ <slot :name="name" />
5
+ </template>
6
+ </el-form-item>
7
+ </template>
8
+
9
+ <script setup>
10
+ defineOptions({
11
+ name: 'MFormItem'
12
+ })
13
+ </script>
14
+
15
+ <style lang="scss">
16
+ // FormItem 组件样式 - 使用 m-form-item 类名隔离样式
17
+ .m-form-item {
18
+ // 自定义样式可以在这里添加
19
+ }
20
+ </style>