@ecolovo/uniapp-components 1.0.0

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 (97) hide show
  1. package/components/aspect/aspect.vue +43 -0
  2. package/components/badge/badge.vue +88 -0
  3. package/components/button/button.vue +409 -0
  4. package/components/checkbox/checkbox.vue +183 -0
  5. package/components/checkbox-group/checkbox-group.vue +101 -0
  6. package/components/checkbox-group2/checkbox-group2.vue +138 -0
  7. package/components/checkbox-group2/checkbox.vue +103 -0
  8. package/components/data-list/data-list.vue +130 -0
  9. package/components/date-picker/date-picker-view.vue +181 -0
  10. package/components/date-picker/date-picker.vue +237 -0
  11. package/components/datetime-picker/datetime-picker-view.vue +209 -0
  12. package/components/datetime-picker/datetime-picker.vue +235 -0
  13. package/components/dialog/dialog-content.vue +162 -0
  14. package/components/dialog/dialog.vue +166 -0
  15. package/components/dropdown/dropdown.vue +145 -0
  16. package/components/empty/empty.vue +102 -0
  17. package/components/flex/flex.vue +76 -0
  18. package/components/form/form.vue +43 -0
  19. package/components/form/mixin.js +13 -0
  20. package/components/form-item/form-item.vue +141 -0
  21. package/components/icon/icon.vue +114 -0
  22. package/components/image/image.vue +61 -0
  23. package/components/input/input.vue +154 -0
  24. package/components/input/password-input.vue +95 -0
  25. package/components/list-page/list-page.js +10 -0
  26. package/components/list-page/list-page.vue +150 -0
  27. package/components/load-more/load-more.vue +97 -0
  28. package/components/loading/animations/loading-animation1.vue +92 -0
  29. package/components/loading/animations/loading-animation2.vue +28 -0
  30. package/components/loading/animations/loading-animation3.vue +81 -0
  31. package/components/loading/animations/loading-animation4.vue +74 -0
  32. package/components/loading/loading.vue +91 -0
  33. package/components/message-box/message-box.vue +60 -0
  34. package/components/number-dialog/number-dialog.vue +360 -0
  35. package/components/number-input/number-input.vue +352 -0
  36. package/components/numpad/numpad.vue +224 -0
  37. package/components/page/page-body.vue +227 -0
  38. package/components/page/page-footer.vue +75 -0
  39. package/components/page/page-header.vue +222 -0
  40. package/components/page/page.vue +128 -0
  41. package/components/picker/picker-popup.vue +295 -0
  42. package/components/picker/picker.vue +151 -0
  43. package/components/popover/popover-content.vue +255 -0
  44. package/components/popover/popover-mask.vue +113 -0
  45. package/components/popover/popover.vue +84 -0
  46. package/components/popup/popup-content.vue +162 -0
  47. package/components/popup/popup.vue +168 -0
  48. package/components/price/price.vue +104 -0
  49. package/components/search/search.vue +220 -0
  50. package/components/searching/searching.vue +86 -0
  51. package/components/selector/selector.vue +86 -0
  52. package/components/switch/switch.vue +180 -0
  53. package/components/tab/tab.vue +235 -0
  54. package/components/table/table.vue +112 -0
  55. package/components/textarea/textarea.vue +192 -0
  56. package/components/time-picker/time-picker-view.vue +127 -0
  57. package/components/time-picker/time-picker.vue +140 -0
  58. package/components/uploader/download.js +81 -0
  59. package/components/uploader/file-uploader.vue +52 -0
  60. package/components/uploader/files.js +225 -0
  61. package/components/uploader/media-uploader.vue +133 -0
  62. package/components/uploader/mixin.js +106 -0
  63. package/components/uploader/uni.js +38 -0
  64. package/components/uploader/upload-button.vue +29 -0
  65. package/components/uploader/uploader copy.vue +547 -0
  66. package/components/uploader/uploader.vue +117 -0
  67. package/configs/index.js +41 -0
  68. package/easyCom.js +25 -0
  69. package/init.js +17 -0
  70. package/mixins/componentName.js +32 -0
  71. package/mixins/listPage.js +1 -0
  72. package/mixins/windowInfo.js +1 -0
  73. package/package.json +12 -0
  74. package/resources/iconfont/uniapp_ui_icon/demo.css +539 -0
  75. package/resources/iconfont/uniapp_ui_icon/demo_index.html +555 -0
  76. package/resources/iconfont/uniapp_ui_icon/iconfont.css +78 -0
  77. package/resources/iconfont/uniapp_ui_icon/iconfont.js +1 -0
  78. package/resources/iconfont/uniapp_ui_icon/iconfont.json +121 -0
  79. package/resources/iconfont/uniapp_ui_icon/iconfont.woff2 +0 -0
  80. package/resources/image/empty.svg +13 -0
  81. package/styles/global.scss +24 -0
  82. package/styles/index.scss +2 -0
  83. package/styles/utils/css-var.scss +87 -0
  84. package/styles/utils/ellipsis.scss +26 -0
  85. package/styles/utils/global-var.scss +11 -0
  86. package/styles/utils/index.scss +5 -0
  87. package/styles/utils/selector.scss +5 -0
  88. package/styles/utils/z-index.scss +10 -0
  89. package/styles/var/component.scss +242 -0
  90. package/styles/var/index.scss +2 -0
  91. package/styles/var/theme.scss +40 -0
  92. package/utils/date.js +151 -0
  93. package/utils/floor.js +20 -0
  94. package/utils/freezeDeep.js +19 -0
  95. package/utils/price.js +32 -0
  96. package/utils/round.js +22 -0
  97. package/utils/windowInfo.js +77 -0
@@ -0,0 +1,162 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <popover-content-cpn position="bottom" :loading="loading">
4
+ <!-- 内容上方标题 -->
5
+ <template #header>
6
+ <slot v-if="$slots.header" name="header"></slot>
7
+ <view v-else-if="title || showClose" :class="$style['PopupContent--header']">
8
+ <view
9
+ :class="[
10
+ $style['PopupContent--title'],
11
+ { [$style['PopupContent--title-center']]: centerTitle },
12
+ ]"
13
+ >
14
+ <slot name="title">
15
+ <text>{{ title }}</text>
16
+ </slot>
17
+ </view>
18
+ <view v-if="showClose" :class="$style['PopupContent--close']" @click="$emit('close')">
19
+ <icon-cpn icon="close" tap-size="80rpx" />
20
+ </view>
21
+ </view>
22
+ </template>
23
+
24
+ <!-- 内容区域 -->
25
+ <slot></slot>
26
+
27
+ <!-- 内容下方操作按钮 -->
28
+ <template #footer>
29
+ <slot v-if="$slots.footer" name="footer"></slot>
30
+ <view v-else-if="cancel || confirm" :class="$style['PopupContent--footer']">
31
+ <view v-if="cancel" :class="$style['PopupContent--button']">
32
+ <button-cpn plain @click="$emit('cancel')">
33
+ {{ cancel }}
34
+ </button-cpn>
35
+ </view>
36
+ <view v-if="confirm" :class="$style['PopupContent--button']">
37
+ <button-cpn @click="$emit('confirm')">
38
+ {{ confirm }}
39
+ </button-cpn>
40
+ </view>
41
+ </view>
42
+ </template>
43
+ </popover-content-cpn>
44
+ </view>
45
+ </template>
46
+
47
+ <script>
48
+ import componentName from '../../mixins/componentName';
49
+ import ButtonCpn from '../button/button.vue';
50
+ import IconCpn from '../icon/icon.vue';
51
+ import PopoverContentCpn from '../popover/popover-content.vue';
52
+
53
+ export default {
54
+ name: 'AppPopupContent',
55
+ options: {
56
+ virtualHost: true,
57
+ styleIsolation: 'shared',
58
+ },
59
+ components: { ButtonCpn, IconCpn, PopoverContentCpn },
60
+ mixins: [componentName],
61
+ props: {
62
+ /** 是否显示 loading 动画 */
63
+ loading: {
64
+ type: Boolean,
65
+ default: false,
66
+ },
67
+ /** 标题 */
68
+ title: {
69
+ type: String,
70
+ default: '',
71
+ },
72
+ /** 是否居中标题 */
73
+ centerTitle: {
74
+ type: Boolean,
75
+ default: false,
76
+ },
77
+ /** 是否显示关闭按钮 */
78
+ showClose: {
79
+ type: Boolean,
80
+ default: true,
81
+ },
82
+ /** 取消按钮文本,为 falsy 时( false 或 '' )不显示 */
83
+ cancel: {
84
+ type: [String, Boolean],
85
+ default: '取消',
86
+ },
87
+ /** 确认按钮文本,为 falsy 时( false 或 '' )不显示 */
88
+ confirm: {
89
+ type: [String, Boolean],
90
+ default: '确认',
91
+ },
92
+ },
93
+ };
94
+ </script>
95
+
96
+ <style lang="scss" module>
97
+ @use '../../styles/index' as *;
98
+
99
+ // 定义外部变量
100
+ $component-name: 'popup';
101
+ $component-vars: $popup;
102
+ %external-vars {
103
+ @include UTILS__DEFINE_COMPONENT_VARS();
104
+ }
105
+
106
+ :host {
107
+ display: block;
108
+ }
109
+
110
+ .PopupContent {
111
+ @extend %external-vars;
112
+ #{UTILS__VAR_NAME(header-height, popover)}: #{UTILS__LOCAL_VAR(header-height)};
113
+ #{UTILS__VAR_NAME(footer-height, popover)}: #{UTILS__LOCAL_VAR(footer-height)};
114
+ #{UTILS__VAR_NAME(padding, popover)}: 20rpx 30rpx;
115
+
116
+ .PopupContent--header {
117
+ position: relative;
118
+ box-sizing: border-box;
119
+ height: UTILS__LOCAL_VAR(header-height);
120
+ padding: 20rpx 30rpx 0rpx;
121
+ display: flex;
122
+ align-items: center;
123
+ }
124
+ .PopupContent--title {
125
+ flex: 1;
126
+ font-size: UTILS__GLOBAL_VAR(font-size, large);
127
+ font-weight: 600;
128
+ &.PopupContent--title-center {
129
+ text-align: center;
130
+ }
131
+ }
132
+ .PopupContent--close {
133
+ position: absolute;
134
+ top: 0;
135
+ right: 20rpx;
136
+ margin-top: 20rpx;
137
+ width: calc(#{UTILS__LOCAL_VAR(header-height)} - 20rpx);
138
+ height: calc(#{UTILS__LOCAL_VAR(header-height)} - 20rpx);
139
+ font-size: 48rpx;
140
+ color: #999;
141
+ display: flex;
142
+ justify-content: center;
143
+ align-items: center;
144
+ }
145
+
146
+ .PopupContent--footer {
147
+ box-sizing: border-box;
148
+ height: UTILS__LOCAL_VAR(footer-height);
149
+ padding: 0 30rpx;
150
+ display: flex;
151
+ align-items: center;
152
+ }
153
+ .PopupContent--button {
154
+ flex: 1;
155
+ #{UTILS__VAR_NAME(height, button)}: 84rpx;
156
+ #{UTILS__VAR_NAME(border-radius, button)}: 20rpx;
157
+ & + #{UTILS__LAST_SELECTOR(&)} {
158
+ margin-left: 20rpx;
159
+ }
160
+ }
161
+ }
162
+ </style>
@@ -0,0 +1,168 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <popover-mask-cpn
4
+ ref="mask"
5
+ :value="value"
6
+ :modal="modal || isLoading"
7
+ @input="$emit('input', $event)"
8
+ @close="$emit('close')"
9
+ @closed="$emit('closed')"
10
+ >
11
+ <slot name="content">
12
+ <popup-content-cpn
13
+ :loading="isLoading"
14
+ :title="title"
15
+ :center-title="centerTitle"
16
+ :show-close="showClose"
17
+ :cancel="cancel"
18
+ :confirm="confirm"
19
+ @close="onClose()"
20
+ @cancel="onButton('cancel', closeOnCancel)"
21
+ @confirm="onButton('confirm', closeOnConfirm)"
22
+ >
23
+ <slot></slot>
24
+ </popup-content-cpn>
25
+ </slot>
26
+ </popover-mask-cpn>
27
+ </view>
28
+ </template>
29
+
30
+ <script>
31
+ import componentName from '../../mixins/componentName';
32
+ import PopoverMaskCpn from '../popover/popover-mask.vue';
33
+ import PopupContentCpn from './popup-content.vue';
34
+
35
+ export default {
36
+ name: 'AppPopup',
37
+ options: {
38
+ virtualHost: true,
39
+ styleIsolation: 'shared',
40
+ },
41
+ components: { PopoverMaskCpn, PopupContentCpn },
42
+ mixins: [componentName],
43
+ props: {
44
+ /** v-model 绑定值,控制对话框是否可见 */
45
+ value: {
46
+ type: Boolean,
47
+ default: false,
48
+ },
49
+ /** 是否模态框 */
50
+ modal: {
51
+ type: Boolean,
52
+ default: false,
53
+ },
54
+ /** 是否显示 loading 动画 */
55
+ loading: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+ /** 标题 */
60
+ title: {
61
+ type: String,
62
+ default: '',
63
+ },
64
+ /** 是否居中标题 */
65
+ centerTitle: {
66
+ type: Boolean,
67
+ default: false,
68
+ },
69
+ /** 是否显示关闭按钮 */
70
+ showClose: {
71
+ type: Boolean,
72
+ default: true,
73
+ },
74
+ /** 取消按钮文本,为 falsy 时( false 或 '' )不显示 */
75
+ cancel: {
76
+ type: [String, Boolean],
77
+ default: '取消',
78
+ },
79
+ /** 点击确认按钮时是否自动关闭对话框 */
80
+ closeOnCancel: {
81
+ type: Boolean,
82
+ default: true,
83
+ },
84
+ /** 确认按钮文本,为 falsy 时( false 或 '' )不显示 */
85
+ confirm: {
86
+ type: [String, Boolean],
87
+ default: '确认',
88
+ },
89
+ /** 点击确认按钮时是否自动关闭对话框 */
90
+ closeOnConfirm: {
91
+ type: Boolean,
92
+ default: true,
93
+ },
94
+ /** 是否异步关闭,使用内部 loading 属性,需手动调用 close 方法关闭 */
95
+ async: {
96
+ type: Boolean,
97
+ default: false,
98
+ },
99
+ },
100
+ data() {
101
+ return {
102
+ isAsyncLoading: false,
103
+ };
104
+ },
105
+ computed: {
106
+ /** 按钮 loading */
107
+ isLoading() {
108
+ return this.loading || this.isAsyncLoading;
109
+ },
110
+ },
111
+ methods: {
112
+ close() {
113
+ this.$refs.mask.close();
114
+ },
115
+ /** 隐藏 */
116
+ onClose() {
117
+ if (this.isLoading) return;
118
+
119
+ this.close();
120
+ },
121
+ /** 点击取消或确认按钮
122
+ * @param {'cancel' | 'confirm'} btnType 按钮类型
123
+ * @param {boolean} shouldClose 是否自动关闭对话框
124
+ */
125
+ onButton(btnType, shouldClose) {
126
+ if (this.isLoading) return;
127
+
128
+ if (btnType === 'confirm' && this.async) {
129
+ this.isAsyncLoading = true;
130
+ const { promise, resolve, reject } = Promise.withResolvers();
131
+ promise
132
+ .then((willClose = true) => {
133
+ if (willClose === false) {
134
+ this.isAsyncLoading = false;
135
+ return;
136
+ }
137
+ this.close();
138
+ })
139
+ .catch((err) => {
140
+ if (process.env.NODE_ENV === 'development') {
141
+ // eslint-disable-next-line no-console
142
+ console.warn(`${this.componentClass} unresolved error:`, err);
143
+ }
144
+ this.isAsyncLoading = false;
145
+ });
146
+ this.$emit(btnType, { resolve, reject });
147
+ return;
148
+ }
149
+
150
+ if (shouldClose) {
151
+ this.$emit(btnType);
152
+ this.close();
153
+ return;
154
+ }
155
+
156
+ this.$emit(btnType, this.$refs.mask.close.bind(this.$refs.mask));
157
+ },
158
+ },
159
+ };
160
+ </script>
161
+
162
+ <style lang="scss" module>
163
+ @use '../../styles/index' as *;
164
+
165
+ :host {
166
+ display: block;
167
+ }
168
+ </style>
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <text :class="componentClassNames">
3
+ <text v-if="prefixUnit" :class="$style['Price--unit']">
4
+ <!-- 默认插槽用于放置单位 -->
5
+ <slot>
6
+ <text :class="$style['Price--default-prefix-unit']">¥</text>
7
+ </slot>
8
+ </text>
9
+ <text v-if="showSymbol || formattedPrice.negative" :class="$style['Price--integer']">
10
+ {{ formattedPrice.negative ? '-' : '+' }}
11
+ </text>
12
+ <text :class="$style['Price--integer']"> {{ formattedPrice.integer }} </text>
13
+ <text v-if="alwaysShowDecimal || formattedPrice.decimal !== '00'" :class="$style['Price--decimal']">
14
+ .{{ formattedPrice.decimal }}
15
+ </text>
16
+ <text v-if="!prefixUnit" :class="$style['Price--unit']">
17
+ <!-- 默认插槽用于放置单位 -->
18
+ <slot></slot>
19
+ </text>
20
+ </text>
21
+ </template>
22
+
23
+ <script>
24
+ import componentName from '../../mixins/componentName';
25
+ import { formatPrice } from '../../utils/price';
26
+
27
+ export default {
28
+ name: 'AppPrice',
29
+ options: {
30
+ virtualHost: true,
31
+ styleIsolation: 'shared',
32
+ },
33
+ mixins: [componentName],
34
+ props: {
35
+ /** 价格 */
36
+ value: {
37
+ type: [Number, String],
38
+ default: 0,
39
+ },
40
+ /** 前置单位 */
41
+ prefixUnit: {
42
+ type: Boolean,
43
+ default: false,
44
+ },
45
+ /** 是否一直显示符号 */
46
+ showSymbol: {
47
+ type: Boolean,
48
+ default: false,
49
+ },
50
+ /** 是否始终显示小数 */
51
+ alwaysShowDecimal: {
52
+ type: Boolean,
53
+ default: true,
54
+ },
55
+ },
56
+ computed: {
57
+ /** 格式化后的价格 */
58
+ formattedPrice() {
59
+ return formatPrice(this.value);
60
+ },
61
+ },
62
+ };
63
+ </script>
64
+
65
+ <style lang="scss" module>
66
+ @use '../../styles/index' as *;
67
+
68
+ // 定义外部变量
69
+ $component-name: 'price';
70
+ $component-vars: $price;
71
+ %external-vars {
72
+ @include UTILS__DEFINE_COMPONENT_VARS();
73
+ }
74
+
75
+ :host {
76
+ display: inline;
77
+ }
78
+
79
+ .Price {
80
+ @extend %external-vars;
81
+ color: UTILS__LOCAL_VAR(color);
82
+ font-size: UTILS__LOCAL_VAR(font-size);
83
+ font-weight: UTILS__LOCAL_VAR(font-weight);
84
+ }
85
+ .Price--default-prefix-unit {
86
+ margin-left: 0.25em;
87
+ margin-right: 0.25em;
88
+ }
89
+ .Price--integer {
90
+ color: UTILS__LOCAL_VAR(integer-color);
91
+ font-size: UTILS__LOCAL_VAR(integer-font-size);
92
+ font-weight: UTILS__LOCAL_VAR(integer-font-weight);
93
+ }
94
+ .Price--decimal {
95
+ color: UTILS__LOCAL_VAR(decimal-color);
96
+ font-size: UTILS__LOCAL_VAR(decimal-font-size);
97
+ font-weight: UTILS__LOCAL_VAR(decimal-font-weight);
98
+ }
99
+ .Price--unit {
100
+ color: UTILS__LOCAL_VAR(unit-color);
101
+ font-size: UTILS__LOCAL_VAR(unit-font-size);
102
+ font-weight: UTILS__LOCAL_VAR(unit-font-weight);
103
+ }
104
+ </style>
@@ -0,0 +1,220 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <view :class="$style['Search--wrapper']">
4
+ <icon-cpn icon="search" :class="[$style['Search--icon'], $style['Search--prefix-icon']]"> </icon-cpn>
5
+ <view
6
+ v-if="readonly"
7
+ :class="[
8
+ $style['Search--text'],
9
+ { [$style['Search--ellipsis']]: ellipsis, [$style['Search--placeholder']]: !searchValue },
10
+ ]"
11
+ >
12
+ {{ searchValue || placeholder }}
13
+ </view>
14
+ <input
15
+ v-else
16
+ :value="searchValue"
17
+ :disabled="disabled"
18
+ :maxlength="maxlength"
19
+ :placeholder="placeholder"
20
+ confirm-type="search"
21
+ :class="$style['Search--input']"
22
+ @input="onInput"
23
+ @confirm="onConfirm"
24
+ />
25
+ <icon-cpn
26
+ v-if="clearable && searchValue"
27
+ icon="close-circle-filled"
28
+ :class="[$style['Search--icon'], $style['Search--close-icon']]"
29
+ @click.native="onClear"
30
+ >
31
+ </icon-cpn>
32
+ </view>
33
+ <button-cpn
34
+ v-if="cancelButton"
35
+ text
36
+ :disabled="!searchValue"
37
+ :class="$style['Search--cancel-button']"
38
+ @click="onCancel"
39
+ >
40
+ 取消
41
+ </button-cpn>
42
+ </view>
43
+ </template>
44
+
45
+ <script>
46
+ import debounce from 'lodash-es/debounce';
47
+ import componentName from '../../mixins/componentName';
48
+ import ButtonCpn from '../button/button.vue';
49
+ import IconCpn from '../icon/icon.vue';
50
+
51
+ export default {
52
+ name: 'AppSearch',
53
+ options: {
54
+ virtualHost: true,
55
+ styleIsolation: 'shared',
56
+ },
57
+ components: { ButtonCpn, IconCpn },
58
+ mixins: [componentName],
59
+ props: {
60
+ /** 搜索文本 */
61
+ value: {
62
+ type: [String, null],
63
+ default: '',
64
+ },
65
+ /** 最大输入文本长度 */
66
+ maxlength: {
67
+ type: Number,
68
+ default: 140,
69
+ },
70
+ /** 占位文本 */
71
+ placeholder: {
72
+ type: String,
73
+ default: '请输入搜索内容',
74
+ },
75
+ /** 防抖时长 */
76
+ debounce: {
77
+ type: Number,
78
+ default: 300,
79
+ },
80
+ /** 是否有清空按钮 */
81
+ clearable: {
82
+ type: Boolean,
83
+ default: true,
84
+ },
85
+ /** 是否只读 */
86
+ readonly: {
87
+ type: Boolean,
88
+ default: false,
89
+ },
90
+ /** 是否显示搜索按钮 */
91
+ cancelButton: {
92
+ type: Boolean,
93
+ default: false,
94
+ },
95
+ /** 当前状态是否可以搜索,仅 `cancelButton` 为 `true` 时有效 */
96
+ searchable: {
97
+ type: Boolean,
98
+ default: true,
99
+ },
100
+ },
101
+ data() {
102
+ return {
103
+ /** 内部搜索值 */
104
+ innerSearchValue: '',
105
+ };
106
+ },
107
+ computed: {
108
+ /** 当前搜索值 */
109
+ searchValue: {
110
+ get: function () {
111
+ return this.value === null ? this.innerSearchValue : this.value;
112
+ },
113
+ set: function (value) {
114
+ this.$emit('input', value);
115
+ this.innerSearchValue = value;
116
+ this.$emit('change', this.innerSearchValue);
117
+ },
118
+ },
119
+ },
120
+ created() {
121
+ this.debouncedInput = debounce((value) => {
122
+ this.$emit('input-search', value);
123
+ }, this.debounce);
124
+ },
125
+ methods: {
126
+ /** 输入响应 */
127
+ onInput(event) {
128
+ this.searchValue = event.detail.value;
129
+ this.debouncedInput(event.detail.value);
130
+ },
131
+ /** 点击键盘搜索按钮响应 */
132
+ onConfirm() {
133
+ this.$emit('search', this.searchValue);
134
+ },
135
+ /** 点击清除按钮响应 */
136
+ onClear() {
137
+ this.searchValue = '';
138
+ this.$emit('clear', '');
139
+ },
140
+ /** 点击取消按钮响应 */
141
+ onCancel() {
142
+ this.searchValue = '';
143
+ this.searchValue = '';
144
+ this.$emit('cancel', '');
145
+ },
146
+ },
147
+ };
148
+ </script>
149
+
150
+ <style lang="scss" module>
151
+ @use '../../styles/index' as *;
152
+
153
+ // 定义外部变量
154
+ $component-name: 'search';
155
+ $component-vars: $search;
156
+ %external-vars {
157
+ @include UTILS__DEFINE_COMPONENT_VARS();
158
+ }
159
+
160
+ :host {
161
+ display: block;
162
+ }
163
+ :host(.display-inline) {
164
+ display: inline;
165
+ }
166
+
167
+ .Search {
168
+ @extend %external-vars;
169
+ display: flex;
170
+ justify-content: center;
171
+ align-items: center;
172
+ width: 100%;
173
+ height: UTILS__LOCAL_VAR(height);
174
+ }
175
+ .Search--wrapper {
176
+ flex: 1 0 auto;
177
+ display: flex;
178
+ justify-content: center;
179
+ align-items: center;
180
+ height: 100%;
181
+ background: UTILS__LOCAL_VAR(background);
182
+ border-radius: UTILS__LOCAL_VAR(border-radius);
183
+ }
184
+ .Search--input,
185
+ .Search--placeholder {
186
+ flex: 1 0 auto;
187
+ width: 0;
188
+ min-width: 0;
189
+ }
190
+ .Search--ellipsis {
191
+ overflow-x: hidden;
192
+ text-overflow: ellipsis;
193
+ white-space: nowrap;
194
+ }
195
+ .Search--placeholder {
196
+ color: UTILS__GLOBAL_VAR(color, placeholder);
197
+ }
198
+ .Search--icon {
199
+ flex: 0 0 auto;
200
+ position: relative;
201
+ font-size: UTILS__GLOBAL_VAR(font-size, large);
202
+ color: UTILS__GLOBAL_VAR(color, placeholder);
203
+ // &::after {
204
+ // content: '';
205
+ // position: absolute;
206
+ // @include absolute-center(UTILS__LOCAL_VAR(height));
207
+ // }
208
+ }
209
+ .Search--divider {
210
+ height: 1em;
211
+ border-right: 2rpx solid #ccc;
212
+ }
213
+ .Search--cancel-button {
214
+ flex: none;
215
+ font-size: UTILS__GLOBAL_VAR(font-size, normal);
216
+ height: 100%;
217
+ #{UTILS__VAR_NAME(color, button)}: #999;
218
+ #{UTILS__VAR_NAME(padding, button)}: 0 0 0 24rpx;
219
+ }
220
+ </style>