v-uni-app-ui 1.0.4 → 1.0.6

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 (89) hide show
  1. package/README.md +62 -82
  2. package/dist/v-uni-app-ui.css +1 -0
  3. package/dist/v-uni-app-ui.es.js +6569 -0
  4. package/dist/v-uni-app-ui.umd.js +7 -0
  5. package/package.json +17 -5
  6. package/components/config/css/basic.scss +0 -19
  7. package/components/config/interface/basic-type.js +0 -16
  8. package/components/config/interface/components-interface.ts +0 -0
  9. package/components/config/interface/monitor/components/input-monitor.js +0 -0
  10. package/components/config/interface/monitor/property-monitor.ts +0 -136
  11. package/components/config/interface/props/basic-props.ts +0 -88
  12. package/components/config/interface/props/components/button-props.ts +0 -85
  13. package/components/config/interface/props/components/input-props.ts +0 -69
  14. package/components/config/interface/props/props-tools.ts +0 -64
  15. package/components/config/style/basic.js +0 -346
  16. package/components/config/style/component-registry.js +0 -142
  17. package/components/config/style/components/button-style.js +0 -160
  18. package/components/config/style/components/input-style.js +0 -98
  19. package/components/config/style/components-style.js +0 -622
  20. package/components/config/style/property-mapper.js +0 -377
  21. package/components/config/style/pseudo-processor.js +0 -213
  22. package/components/config.js +0 -123
  23. package/components/icon/iconfont.css +0 -87
  24. package/components/icon/iconfont.js +0 -1
  25. package/components/icon/iconfont.json +0 -135
  26. package/components/icon/iconfont.ttf +0 -0
  27. package/components/icon/iconfont.woff +0 -0
  28. package/components/icon/iconfont.woff2 +0 -0
  29. package/components/layout/v-card/v-card.vue +0 -108
  30. package/components/layout/v-grid/v-grid.vue +0 -162
  31. package/components/layout/v-icon-grid/v-icon-grid.vue +0 -195
  32. package/components/layout/v-infinite-scroll/v-infinite-scroll.vue +0 -172
  33. package/components/layout/v-list/v-list.vue +0 -43
  34. package/components/layout/v-row/v-row.vue +0 -142
  35. package/components/layout/v-waterfall/v-waterfall.vue +0 -79
  36. package/components/model/compound/v-checkbox-group/v-checkbox-group.vue +0 -96
  37. package/components/model/compound/v-console/v-console.js +0 -20
  38. package/components/model/compound/v-console/v-console.vue +0 -299
  39. package/components/model/compound/v-date-time/v-date-time.vue +0 -261
  40. package/components/model/compound/v-dialog/v-dialog.vue +0 -178
  41. package/components/model/compound/v-drum-select-picker/v-drum-select-picker.vue +0 -83
  42. package/components/model/compound/v-form/v-form.vue +0 -226
  43. package/components/model/compound/v-form-item/v-form-item.vue +0 -255
  44. package/components/model/compound/v-image/v-image.vue +0 -357
  45. package/components/model/compound/v-input-desensitize/v-input-desensitize.vue +0 -101
  46. package/components/model/compound/v-page/v-page.vue +0 -11
  47. package/components/model/compound/v-pages/v-pages.vue +0 -141
  48. package/components/model/compound/v-picker-list/v-picker-list.vue +0 -109
  49. package/components/model/compound/v-popup/v-popup.vue +0 -151
  50. package/components/model/compound/v-radio-group/v-radio-group.vue +0 -86
  51. package/components/model/compound/v-select-picker/v-select-picker.vue +0 -202
  52. package/components/model/compound/v-series-picker-list/v-series-picker-list.vue +0 -221
  53. package/components/model/compound/v-series-select-picker/v-series-select-picker.vue +0 -203
  54. package/components/model/compound/v-switch/v-switch.vue +0 -136
  55. package/components/model/compound/v-tabs-page/v-tabs-page.vue +0 -138
  56. package/components/model/native/v-badge/v-badge.vue +0 -143
  57. package/components/model/native/v-button/v-button.vue +0 -81
  58. package/components/model/native/v-carousel/v-carousel.vue +0 -138
  59. package/components/model/native/v-checkbox/v-checkbox.vue +0 -215
  60. package/components/model/native/v-collapse/v-collapse.vue +0 -190
  61. package/components/model/native/v-header-navigation-bar/v-header-navigation-bar.vue +0 -92
  62. package/components/model/native/v-input/v-input.vue +0 -163
  63. package/components/model/native/v-input-code/v-input-code.vue +0 -146
  64. package/components/model/native/v-loading/v-loading.vue +0 -206
  65. package/components/model/native/v-menu/v-menu.vue +0 -222
  66. package/components/model/native/v-menu-slide/v-menu-slide.vue +0 -364
  67. package/components/model/native/v-min-loading/v-min-loading.vue +0 -80
  68. package/components/model/native/v-null/v-null.vue +0 -97
  69. package/components/model/native/v-overlay/v-overlay.vue +0 -96
  70. package/components/model/native/v-pull-up-refresh/v-pull-up-refresh.vue +0 -157
  71. package/components/model/native/v-radio/v-radio.vue +0 -138
  72. package/components/model/native/v-scroll-list/v-scroll-list.vue +0 -169
  73. package/components/model/native/v-steps/v-steps.vue +0 -253
  74. package/components/model/native/v-table/v-table.vue +0 -203
  75. package/components/model/native/v-tabs/v-tabs.vue +0 -235
  76. package/components/model/native/v-tag/v-tag.vue +0 -206
  77. package/components/model/native/v-text/v-text.vue +0 -187
  78. package/components/model/native/v-textarea/v-textarea.vue +0 -178
  79. package/components/model/native/v-title/v-title.vue +0 -91
  80. package/components/model/native/v-toast/info.png +0 -0
  81. package/components/model/native/v-toast/success.png +0 -0
  82. package/components/model/native/v-toast/v-toast.vue +0 -198
  83. package/components/model/native/v-toast/warn.png +0 -0
  84. package/components/model/native/v-upload-file-button/v-upload-file-button.vue +0 -296
  85. package/components/model/native/v-video/v-video.vue +0 -175
  86. package/components/model/native/v-window/v-window.vue +0 -158
  87. package/components/utils/event-modifiers.ts +0 -139
  88. package/components/utils/validator.ts +0 -451
  89. package/index.js +0 -372
@@ -1,190 +0,0 @@
1
- <template>
2
- <view class="v-collapse">
3
- <view v-for="(item, index) in items" :key="index" :class="['collapse-item', { expanded: item.expanded }]">
4
- <view class="collapse-header" @click="toggleItem(index)">
5
- <view class="header-title">{{ item.title }}</view>
6
- <view v-if="!item.isRightIcon" class="header-icon">
7
- <view class="arrow" :class="{ rotated: item.expanded }"></view>
8
- </view>
9
- </view>
10
- <view class="collapse-content">
11
- <view class="content-inner">
12
- <slot name="content" :item="item">
13
- {{ item.content }}
14
- </slot>
15
- </view>
16
- </view>
17
- </view>
18
- </view>
19
- </template>
20
-
21
- <script lang="ts" setup>
22
- import { ref, watch,inject } from 'vue';
23
-
24
- interface CollapseItem {
25
- title: string;
26
- content: string;
27
- expanded: boolean;
28
- name?: string;
29
- isRightIcon?: boolean;
30
- }
31
-
32
- const props = defineProps({
33
- items: {
34
- type: Array as () => CollapseItem[],
35
- required: true,
36
- default: () => []
37
- },
38
- accordion: {
39
- type: Boolean,
40
- default: true
41
- },
42
- activeIndex: {
43
- type: Number,
44
- default: 0
45
- }
46
- });
47
-
48
- const emit = defineEmits(['update:activeIndex', 'change']);
49
-
50
- const config = inject<any>('config');
51
- const items = ref<CollapseItem[]>([...props.items]);
52
-
53
- const initExpandedState = () => {
54
- items.value.forEach((item, index) => {
55
- item.expanded = index === props.activeIndex;
56
- });
57
- };
58
-
59
- watch(
60
- () => props.activeIndex,
61
- (newIndex) => {
62
- if (props.accordion) {
63
- items.value.forEach((item, index) => {
64
- item.expanded = index === newIndex;
65
- });
66
- }
67
- }
68
- );
69
-
70
- initExpandedState();
71
-
72
- const toggleItem = (index: number) => {
73
- const item = items.value[index];
74
-
75
- if (props.accordion) {
76
- items.value.forEach((otherItem, otherIndex) => {
77
- otherItem.expanded = otherIndex === index ? !item.expanded : false;
78
- });
79
- } else {
80
- item.expanded = !item.expanded;
81
- }
82
-
83
- const activeIndex = items.value.findIndex((item) => item.expanded);
84
- emit('update:activeIndex', activeIndex);
85
- emit('change', activeIndex);
86
- };
87
- </script>
88
-
89
- <style lang="scss" scoped>
90
- .v-collapse {
91
- width: 100%;
92
- overflow: hidden;
93
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
94
-
95
- .collapse-item {
96
- margin-bottom: 12rpx;
97
- overflow: hidden;
98
- background: transparent;
99
- transition: all 0.5s ease;
100
- border-top: 1rpx solid v-bind("config.border.color");
101
- border-bottom: 1rpx solid v-bind("config.border.color");
102
-
103
- &:last-child {
104
- margin-bottom: 0;
105
- }
106
-
107
- .collapse-header {
108
- display: flex;
109
- justify-content: space-between;
110
- align-items: center;
111
- padding: 18rpx 24rpx;
112
- font-weight: 600;
113
- font-size: 24rpx;
114
- cursor: pointer;
115
- transition: all 0.3s ease;
116
- }
117
-
118
- .header-icon {
119
- width: 24rpx;
120
- height: 24rpx;
121
- display: flex;
122
- align-items: center;
123
- justify-content: center;
124
-
125
- .arrow {
126
- width: 15rpx;
127
- height: 15rpx;
128
- border-right: 4rpx solid v-bind("config.border.color");
129
- border-bottom: 4rpx solid v-bind("config.border.color");
130
- transform: rotate(45deg);
131
- transition: transform 0.5s ease;
132
- }
133
-
134
- .rotated {
135
- transform: rotate(225deg);
136
- }
137
- }
138
-
139
- .collapse-content {
140
- max-height: 0;
141
- overflow: hidden;
142
- transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.5s;
143
- box-shadow: 0 4rpx 6rpx rgba(0, 0, 0, 0.05);
144
- }
145
-
146
- .content-inner {
147
- padding: 24rpx;
148
- line-height: 1.7;
149
- transform: translateY(10rpx);
150
- opacity: 0;
151
- transition: transform 0.3s ease, opacity 0.3s ease;
152
- }
153
-
154
- &.expanded .collapse-content {
155
- max-height: 1000rpx;
156
- }
157
-
158
- &.expanded .content-inner {
159
- transform: translateY(0);
160
- opacity: 1;
161
- transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
162
- }
163
-
164
- // 响应式设计
165
- @media (max-width: 768px) {
166
- .collapse-header {
167
- padding: 16rpx 20rpx;
168
- font-size: v-bind("config.fontSize.mediumTitle");
169
- }
170
-
171
- .content-inner {
172
- padding: 20rpx;
173
- font-size: v-bind("config.fontSize.largeText");
174
- }
175
- }
176
-
177
- @media (max-width: 480px) {
178
- .collapse-header {
179
- padding: 14rpx 16rpx;
180
- font-size: v-bind("config.fontSize.smallTitle");
181
- }
182
-
183
- .content-inner {
184
- padding: 16rpx;
185
- font-size: v-bind("config.fontSize.mediumText");
186
- }
187
- }
188
- }
189
- }
190
- </style>
@@ -1,92 +0,0 @@
1
- <template>
2
- <view class="v-header-navigation-bar" :style="{ backgroundColor: backgroundColor }">
3
- <view class="v-header-navigation-bar-left" @click="handleBack">
4
- <slot name="left">
5
- <view class="v-header-navigation-bar-back-icon" v-if="showBack"></view>
6
- </slot>
7
- </view>
8
- <view class="v-header-navigation-bar-title">
9
- <slot>
10
- <text>{{ title }}</text>
11
- </slot>
12
- </view>
13
- <view class="v-header-navigation-bar-right">
14
- <slot name="right"></slot>
15
- </view>
16
- </view>
17
- </template>
18
-
19
- <script lang="ts" setup>
20
- import { ref,inject } from 'vue';
21
-
22
- /**
23
- * v-header-navigation-bar 导航栏
24
- * title 标题
25
- * backgroundColor 背景颜色
26
- * showBack 是否需要返回按钮
27
- */
28
- const props = defineProps({
29
- title: {
30
- type: String,
31
- default: ''
32
- },
33
- backgroundColor: {
34
- type: String,
35
- default: '#ffffff'
36
- },
37
- showBack: {
38
- type: Boolean,
39
- default: true
40
- }
41
- });
42
-
43
- const emits = defineEmits(['back']);
44
-
45
- const config = inject<any>('config');
46
- const handleBack = () => {
47
- if (props.showBack) {
48
- emits('back');
49
- }
50
- };
51
- </script>
52
-
53
- <style lang="scss" scoped>
54
- .v-header-navigation-bar {
55
- display: flex;
56
- align-items: center;
57
- justify-content: space-between;
58
- padding: 10rpx 16rpx;
59
- box-sizing: border-box;
60
- height: 5vh;
61
- border-bottom: 1px solid v-bind("config.border.color");
62
- position: relative;
63
- z-index: 1000;
64
- }
65
- .v-header-navigation-bar-left {
66
- margin-left: 2%;
67
- }
68
- .v-header-navigation-bar-left,
69
- .v-header-navigation-bar-right {
70
- display: flex;
71
- align-items: center;
72
- }
73
-
74
- .v-header-navigation-bar-back-icon {
75
- width: 24rpx;
76
- height: 24rpx;
77
- border: 4rpx solid v-bind("config.fontColor.mianTitle");
78
- border-top: none;
79
- border-right: none;
80
- transform: rotate(45deg);
81
- margin-right: 10px;
82
- cursor: pointer;
83
- }
84
-
85
- .v-header-navigation-bar-title {
86
- flex: 1;
87
- text-align: center;
88
- font-size: v-bind("config.fontSize.mediumTitle");
89
- font-weight: bold;
90
- color: v-bind("config.fontColor.mianTitle");
91
- }
92
- </style>
@@ -1,163 +0,0 @@
1
- <template>
2
- <view :id="props.id" :class="computedClasses" :style="computedStyle">
3
- <view :style="leftSlotStyle" class="left-slot">
4
- <slot name="left">
5
- <view class="left-icon" v-if="props.isIcon" :style="iconStyle">
6
- <view class="iconfont icon-url"></view>
7
- <view class="icon-fill" :style="iconFillStyle"></view>
8
- </view>
9
- </slot>
10
- </view>
11
- <view :style="inputStyle" class="center-input">
12
- <input
13
- v-model="inputValue"
14
- :type="computedInputType"
15
- :style="inputFontStyle"
16
- :placeholder="currentPlaceholder"
17
- :disabled="props.disabled"
18
- :placeholder-style="toCSS(inputPlaceholderStyle)"
19
- :cursor="props.cursor"
20
- :selection-start="selectionStart"
21
- :selection-end="selectionEnd"
22
- :maxlength="props.maxlength"
23
- :random-number="props.randomNumber"
24
- :cursor-color="props.cursorColor"
25
- :focus="props.focus"
26
- :auto-blur="props.autoBlur"
27
- :password="props.type === 'password'"
28
- :cursor-spacing="props.cursorSpacing"
29
- @focus="focus(true)"
30
- @blur="focus(false)"
31
- />
32
- </view>
33
- <view :style="rightSlotStyle" class="right-slot">
34
- <slot name="right"></slot>
35
- </view>
36
- </view>
37
- </template>
38
-
39
- <script setup lang="ts">
40
- import { ref, onUnmounted, computed } from 'vue';
41
- import inputProps from '@/components/config/interface/props/components/input-props';
42
- import { useComponentStyle } from '@/components/config/style/components-style';
43
- import { usePropertyMonitor } from '@/components/config/interface/monitor/property-monitor';
44
-
45
- const props = defineProps(inputProps);
46
- const emit = defineEmits<{
47
- input: [value: string];
48
- blur: [event: FocusEvent];
49
- focus: [event: FocusEvent];
50
- 'update:value': [value: any];
51
- 'update:placeholderConfig': [value: any];
52
- 'update:disabled': [value: any];
53
- }>();
54
-
55
- const { style: computedStyle, classes: computedClasses, sonStyle, toCSS, focus } = useComponentStyle('input', props);
56
- const getSonStyle = (element: string): Record<string, string | number> => {
57
- return sonStyle.value[element as keyof typeof sonStyle.value] || {};
58
- };
59
- const inputPlaceholderStyle = computed(() => {
60
- return Object.assign(getSonStyle('placeholder'), props.placeholderStyle);
61
- });
62
- const inputStyle = computed(() => getSonStyle('input'));
63
- const inputFontStyle = computed(() => {
64
- const { width, height, margin, padding, ...fontStyles } = inputStyle.value;
65
- return fontStyles;
66
- });
67
- const leftSlotStyle = computed(() => getSonStyle('leftSlot'));
68
- const rightSlotStyle = computed(() => getSonStyle('rightSlot'));
69
- const iconStyle = computed(() => getSonStyle('icon'));
70
- const iconFillStyle = computed(() => getSonStyle('iconFill'));
71
- const computedInputType = computed(() => {
72
- const typeMap: Record<string, string> = {
73
- text: 'text',
74
- id: 'idcard',
75
- password: 'text',
76
- 'safe-password': 'safe-password',
77
- number: 'number',
78
- digit: 'digit',
79
- numeric: 'numeric',
80
- decimal: 'decimal',
81
- email: 'email',
82
- phone: 'tel',
83
- url: 'url',
84
- textarea: 'text', // uni-app 的 input 不支持 textarea,需用单独的 textarea 组件,此处降级为 text
85
- name: 'nickname',
86
- search: 'search',
87
- none: 'none'
88
- };
89
-
90
- return typeMap[props.type] || 'text';
91
- });
92
- const currentPlaceholderIndex = ref(0);
93
- const currentPlaceholder = computed(() => {
94
- const placeholder = props.placeholder;
95
- if (!placeholder || placeholder.length === 0) return '';
96
- const index = currentPlaceholderIndex.value % placeholder.length;
97
- return placeholder[index];
98
- });
99
-
100
- // 定时器管理
101
- let placeholderTimer: ReturnType<typeof setInterval> | null = null;
102
-
103
- const managePlaceholderRotation = () => {
104
- // 清理现有定时器
105
- if (placeholderTimer) {
106
- clearInterval(placeholderTimer);
107
- placeholderTimer = null;
108
- }
109
-
110
- // 启动条件:未被禁用 且 配置有效
111
- if (!props.disabled && props.placeholder && props.placeholder.length > 1 && props.placeholderTimeNumber > 0) {
112
- placeholderTimer = setInterval(() => {
113
- const placeholderArray = Array.isArray(props.placeholder) ? props.placeholder : [props.placeholder!];
114
- currentPlaceholderIndex.value = (currentPlaceholderIndex.value + 1) % placeholderArray.length;
115
- }, props.placeholderTimeNumber);
116
- }
117
- };
118
-
119
- const inputValue = computed({
120
- get: () => props.value,
121
- set: (newValue) => {
122
- emit('update:value', newValue);
123
- }
124
- });
125
-
126
- usePropertyMonitor({ source: inputValue, propertyName: 'value' }, emit);
127
- usePropertyMonitor(
128
- {
129
- source: () => props.disabled,
130
- propertyName: 'disabled',
131
- // 状态变化时重新管理定时器
132
- onChange: managePlaceholderRotation
133
- },
134
- emit
135
- );
136
- usePropertyMonitor(
137
- {
138
- source: () => ({
139
- placeholder: props.placeholder,
140
- time: props.placeholderTimeNumber
141
- }),
142
- propertyName: 'placeholderConfig',
143
- onChange: managePlaceholderRotation,
144
- immediate: true
145
- },
146
- emit
147
- );
148
-
149
- onUnmounted(() => {
150
- if (placeholderTimer) {
151
- clearInterval(placeholderTimer);
152
- placeholderTimer = null;
153
- }
154
- });
155
- </script>
156
-
157
- <style lang="scss" scoped>
158
- uni-input {
159
- height: 100%;
160
- min-height: auto;
161
- line-height: normal;
162
- }
163
- </style>
@@ -1,146 +0,0 @@
1
- <template>
2
- <div class="v-input-code">
3
- <div class="input-box" :style="{ width: `${inputWidth * length + (length - 1) * 20}px`, height: `${inputHeight}px` }">
4
- <input
5
- v-for="(item, index) in length"
6
- :key="index"
7
- type="text"
8
- :class="['input-item', { 'input-focus': focusIndex === index }]"
9
- :maxlength="1"
10
- :placeholder="placeholder"
11
- @input="onInput(index, $event)"
12
- @focus="onFocus(index)"
13
- @blur="onBlur(index)"
14
- @keydown="onkeydown(index, $event)"
15
- :focus="inputFocus[index]"
16
- :blur="inputBlur[index]"
17
- />
18
- </div>
19
- </div>
20
- </template>
21
-
22
- <script lang="ts" setup>
23
- import { ref, watch, onMounted, inject } from 'vue';
24
-
25
- const props = defineProps({
26
- value: {
27
- type: String,
28
- default: ''
29
- },
30
- length: {
31
- type: Number,
32
- default: 4
33
- },
34
- inputWidth: {
35
- type: Number,
36
- default: 30
37
- },
38
- inputHeight: {
39
- type: Number,
40
- default: 50
41
- },
42
- focus: {
43
- type: Boolean,
44
- default: false
45
- },
46
- placeholder: {
47
- type: String,
48
- default: ''
49
- }
50
- });
51
-
52
- const emit = defineEmits(['update:value', 'complete']);
53
-
54
- const config = inject<any>('config');
55
- const focusIndex = ref<number | null>(null);
56
- const inputFocus = ref([]);
57
- const inputBlur = ref([]);
58
-
59
- onMounted(() => {
60
- inputFocus.value.length = props.length;
61
- inputBlur.value.length = props.length;
62
- });
63
-
64
- const onInput = (index: number, event: any) => {
65
- const value = event.detail.value;
66
- if (value) {
67
- if (index < props.length - 1) {
68
- console.log(index + 1);
69
- inputFocus.value[index + 1] = true;
70
- }
71
- updateModelValue(value, index);
72
- } else {
73
- updateModelValue('', index);
74
- }
75
- };
76
- const onkeydown = (index: number, event: any) => {
77
- if (event.code === 'Backspace') {
78
- inputFocus.value[index] = false;
79
- // inputFocus.value[index - 2] = false;
80
- // inputFocus.value[index - 2] = true;
81
- }
82
- };
83
-
84
- const onFocus = (index: number) => {
85
- focusIndex.value = index;
86
- };
87
-
88
- const onBlur = (index: number) => {
89
- if (focusIndex.value === index) {
90
- focusIndex.value = null;
91
- }
92
- };
93
-
94
- const updateModelValue = (value: string, index: number) => {
95
- const newValue = props.value.split('');
96
- newValue[index] = value;
97
- const joinedValue = newValue.join('');
98
- emit('update:value', joinedValue);
99
- if (joinedValue.length === props.length) {
100
- emit('complete');
101
- }
102
- };
103
-
104
- watch(
105
- () => props.focus,
106
- (newValue) => {
107
- if (newValue) {
108
- inputFocus.value[0].focus();
109
- }
110
- }
111
- );
112
- </script>
113
-
114
- <style lang="scss" scoped>
115
- .v-input-code {
116
- display: flex;
117
- justify-content: center;
118
- align-items: center;
119
- }
120
-
121
- .input-box {
122
- display: flex;
123
- justify-content: center;
124
- align-items: center;
125
- }
126
-
127
- .input-item {
128
- width: v-bind("inputWidth + 'rpx'");
129
- height: v-bind("inputHeight + 'rpx'");
130
- margin: 0 15rpx;
131
- padding: 0 15rpx;
132
- text-align: center;
133
- font-size: 16px;
134
- border-bottom: 4rpx solid v-bind("config.border.color");
135
- outline: none;
136
- transition: all 0.3s ease;
137
- }
138
-
139
- .input-item:focus {
140
- border-bottom: 4rpx solid v-bind("config.border.default");
141
- }
142
-
143
- .input-focus {
144
- border-bottom: 4rpx solid v-bind("config.border.default");
145
- }
146
- </style>