@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,222 @@
1
+ <template>
2
+ <view
3
+ :class="[componentClassNames, theme === 'dark' ? $style['PageHeader--dark'] : $style['PageHeader--light']]"
4
+ :style="styleStr"
5
+ >
6
+ <!-- 标题栏 -->
7
+ <view
8
+ :class="[
9
+ $style['PageHeader--title-bar'],
10
+ {
11
+ [$style['PageHeader--title-icon-1']]: iconCount === 1,
12
+ [$style['PageHeader--title-icon-2']]: iconCount === 2,
13
+ },
14
+ ]"
15
+ >
16
+ <view :class="$style['PageHeader--nav-icon']">
17
+ <navigator
18
+ v-if="hasBack"
19
+ open-type="navigateBack"
20
+ :class="$style['PageHeader--back-icon']"
21
+ hover-class="none"
22
+ >
23
+ <icon-cpn icon="nav-back"></icon-cpn>
24
+ </navigator>
25
+ <navigator
26
+ v-if="hasHome"
27
+ :url="homePageUrl"
28
+ open-type="reLaunch"
29
+ :class="$style['PageHeader--home-icon']"
30
+ hover-class="none"
31
+ >
32
+ <icon-cpn icon="nav-home"></icon-cpn>
33
+ </navigator>
34
+ </view>
35
+ <view
36
+ :class="[
37
+ $style['PageHeader--title'],
38
+ $style['PageHeader--title-ellipsis'],
39
+ { 'PageHeader--title-center': center },
40
+ ]"
41
+ >
42
+ <slot>{{ title }}</slot>
43
+ </view>
44
+ </view>
45
+ <!-- 标题栏下的额外内容,需设置高度 -->
46
+ <view :class="$style['PageHeader--extra']">
47
+ <slot name="extra"></slot>
48
+ </view>
49
+ </view>
50
+ </template>
51
+
52
+ <script>
53
+ /**
54
+ * 页面头部部分容器组件,不单独使用,通过 page 组件间接引入
55
+ */
56
+
57
+ import componentName from '../../mixins/componentName';
58
+ import windowInfoMixin from '../../mixins/windowInfo';
59
+ import IconCpn from '../icon/icon.vue';
60
+
61
+ export default {
62
+ name: 'AppPageHeader',
63
+ options: {
64
+ virtualHost: true,
65
+ styleIsolation: 'shared',
66
+ },
67
+ components: { IconCpn },
68
+ mixins: [componentName, windowInfoMixin],
69
+ props: {
70
+ /** 导航栏标题 */
71
+ title: {
72
+ type: String,
73
+ default: '',
74
+ },
75
+ /** 导航栏标题是否居中显示 */
76
+ center: {
77
+ type: Boolean,
78
+ default: false,
79
+ },
80
+ /** 主题,只能是 'light' 和 'dark' 中的一个 */
81
+ theme: {
82
+ type: String,
83
+ default: 'light',
84
+ },
85
+ /** 导航按钮类型: 0 = 不显示,1 = 返回,2 = 首页,3 = 返回|首页 */
86
+ navType: {
87
+ type: Number,
88
+ default: 1,
89
+ },
90
+ },
91
+ computed: {
92
+ /** 首页路径 */
93
+ homePageUrl() {
94
+ // TODO HOME_PATH
95
+ return process.env.VUE_APP_HOME_PATH;
96
+ },
97
+ /** 是否显示返回按钮 */
98
+ hasBack() {
99
+ return this.navType & 1;
100
+ },
101
+ /** 是否显示首页按钮 */
102
+ hasHome() {
103
+ return this.navType & 2;
104
+ },
105
+ /** 导航按钮个数 */
106
+ iconCount() {
107
+ return Math.ceil(this.navType / 2);
108
+ },
109
+ styleStr() {
110
+ return [
111
+ `--title-bar-top: ${this.navBarTopOffset}px;`,
112
+ `--title-bar-height: ${this.navBarHeight}px;`,
113
+ `--title-bar-bottom: ${this.navBarBottomOffset}px;`,
114
+ `--menu-button-width: ${this.menuButtonWidth};`,
115
+ ].join(' ');
116
+ },
117
+ },
118
+ };
119
+ </script>
120
+
121
+ <style lang="scss" module>
122
+ @use '../../styles/index' as *;
123
+
124
+ // 定义外部变量
125
+ $component-name: 'page-header';
126
+ $component-vars: $page-header;
127
+ %external-vars {
128
+ @include UTILS__DEFINE_COMPONENT_VARS();
129
+ }
130
+
131
+ :host {
132
+ display: block;
133
+ }
134
+
135
+ .PageHeader {
136
+ @extend %external-vars;
137
+ position: fixed;
138
+ top: 0;
139
+ left: 0;
140
+ width: 100%;
141
+ overflow: hidden; // BFC
142
+ background: UTILS__LOCAL_VAR(background);
143
+ z-index: UTILS__z-index();
144
+ }
145
+
146
+ // 亮色主题对应样式
147
+ .PageHeader--light {
148
+ color: UTILS__LOCAL_VAR(color-light);
149
+ }
150
+ // 暗色主题对应样式
151
+ .PageHeader--dark {
152
+ color: UTILS__LOCAL_VAR(color-dark);
153
+ }
154
+
155
+ // 标题栏
156
+ .PageHeader--title-bar {
157
+ position: relative;
158
+ font-size: UTILS__LOCAL_VAR(font-size);
159
+ font-weight: 600;
160
+ margin-top: var(--title-bar-top);
161
+ width: 100%;
162
+ height: var(--title-bar-height);
163
+ line-height: var(--title-bar-height);
164
+ overflow: hidden;
165
+ }
166
+ // 标题栏中的返回按钮
167
+ .PageHeader--nav-icon {
168
+ position: absolute;
169
+ top: 0;
170
+ left: 10rpx;
171
+ }
172
+ .PageHeader--back-icon,
173
+ .PageHeader--home-icon {
174
+ width: var(--title-bar-height);
175
+ height: var(--title-bar-height);
176
+ display: inline-flex;
177
+ justify-content: center;
178
+ align-items: center;
179
+ }
180
+ .PageHeader--title-icon-2 {
181
+ .PageHeader--nav-icon::before {
182
+ content: '';
183
+ display: block;
184
+ position: absolute;
185
+ top: 50%;
186
+ left: 50%;
187
+ height: 50%;
188
+ width: 2px;
189
+ background: #555;
190
+ border-radius: 1px;
191
+ transform: translate(-50%, -50%);
192
+ }
193
+ }
194
+ // 标题
195
+ .PageHeader--title {
196
+ --title-bar-left-padding: 20rpx;
197
+ width: 100%;
198
+ padding: 0 var(--menu-button-width) 0 var(--title-bar-left-padding);
199
+ box-sizing: border-box;
200
+ &.PageHeader--title-ellipsis {
201
+ overflow: hidden;
202
+ white-space: nowrap;
203
+ text-overflow: ellipsis;
204
+ }
205
+ .PageHeader--title-icon-1 & {
206
+ --title-bar-left-padding: calc(var(--title-bar-height) + 20rpx);
207
+ }
208
+ .PageHeader--title-icon-2 & {
209
+ --title-bar-left-padding: calc(var(--title-bar-height) * 2 + 20rpx);
210
+ }
211
+ &.PageHeader--title-center {
212
+ text-align: center;
213
+ padding: 0 max(var(--title-bar-left-padding), var(--menu-button-width));
214
+ }
215
+ }
216
+
217
+ .PageHeader--extra {
218
+ width: 100%;
219
+ height: UTILS__LOCAL_VAR(extra-height);
220
+ overflow: hidden;
221
+ }
222
+ </style>
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <page-header-cpn v-if="custom" :theme="theme" :title="title">
4
+ <template #extra>
5
+ <slot name="header-extra"></slot>
6
+ </template>
7
+ </page-header-cpn>
8
+
9
+ <page-body-cpn
10
+ ref="body"
11
+ :has-custom-nav="custom"
12
+ :has-footer="hasFooter && $slots.footer"
13
+ :use-scroll="useScroll"
14
+ :is-tab-page="isTabPage"
15
+ :enable-refresh="enableRefresh"
16
+ :refreshing="refreshing"
17
+ @scroll="$emit('scroll', $event)"
18
+ @refresh="$emit('refresh')"
19
+ @reach-bottom="$emit('reach-bottom')"
20
+ >
21
+ <slot></slot>
22
+ </page-body-cpn>
23
+
24
+ <page-footer-cpn v-if="hasFooter && $slots.footer" :is-tab-page="isTabPage">
25
+ <slot name="footer"></slot>
26
+ </page-footer-cpn>
27
+
28
+ <loading-cpn v-if="loading" :title="loading === true ? '加载中...' : loading" />
29
+ </view>
30
+ </template>
31
+
32
+ <script>
33
+ import componentName from '../../mixins/componentName';
34
+ import LoadingCpn from '../loading/loading.vue';
35
+ import PageBodyCpn from './page-body.vue';
36
+ import PageFooterCpn from './page-footer.vue';
37
+ import PageHeaderCpn from './page-header.vue';
38
+
39
+ export default {
40
+ name: 'AppPage',
41
+ options: {
42
+ virtualHost: true,
43
+ styleIsolation: 'shared',
44
+ },
45
+ components: { LoadingCpn, PageBodyCpn, PageFooterCpn, PageHeaderCpn },
46
+ mixins: [componentName],
47
+ props: {
48
+ /** 页面标题 */
49
+ title: {
50
+ type: String,
51
+ default: '',
52
+ },
53
+ /** 是否使用自定义导航栏 */
54
+ custom: {
55
+ type: Boolean,
56
+ default: true,
57
+ },
58
+ /** 是否使用底部操作栏 */
59
+ hasFooter: {
60
+ type: Boolean,
61
+ default: true,
62
+ },
63
+ /** 是否使用scroll-view */
64
+ useScroll: {
65
+ type: Boolean,
66
+ default: true,
67
+ },
68
+ /** 是否启用下拉刷新,仅 useScroll 为 true 时有效 */
69
+ enableRefresh: {
70
+ type: Boolean,
71
+ default: false,
72
+ },
73
+ /** 是否触发下拉刷新,仅 useScroll 为 true 时有效 */
74
+ refreshing: {
75
+ type: [Boolean, null],
76
+ default: null,
77
+ },
78
+ /** 页面加载 */
79
+ loading: {
80
+ type: [Boolean, String],
81
+ default: false,
82
+ },
83
+ /** 分页大小 */
84
+ pageSize: {
85
+ type: [Number, String],
86
+ default: 0,
87
+ },
88
+ /** 是否显示加载更多 */
89
+ showLoadMore: {
90
+ type: Boolean,
91
+ default: true,
92
+ },
93
+ /** 页面头部样式,主要用于控制导航栏字体颜色 */
94
+ theme: {
95
+ type: String,
96
+ default: 'light',
97
+ },
98
+ },
99
+ computed: {
100
+ isTabPage() {
101
+ return false;
102
+ },
103
+ },
104
+ };
105
+ </script>
106
+
107
+ <style lang="scss" module>
108
+ @use '../../styles/index' as *;
109
+
110
+ // 定义外部变量
111
+ $component-name: 'page';
112
+ $component-vars: $page;
113
+ %external-vars {
114
+ @include UTILS__DEFINE_COMPONENT_VARS();
115
+ }
116
+
117
+ :host {
118
+ display: block;
119
+ }
120
+
121
+ .Page {
122
+ @extend %external-vars;
123
+
124
+ width: 100vw;
125
+ position: relative;
126
+ background: var(--background);
127
+ }
128
+ </style>
@@ -0,0 +1,295 @@
1
+ <template>
2
+ <popup-cpn ref="popup" :value="value" :class="componentClassNames" @input="$emit('input', $event)">
3
+ <template #content>
4
+ <popup-content-cpn
5
+ :loading="isLoading"
6
+ :title="title"
7
+ :center-title="false"
8
+ :cancel="false"
9
+ :confirm="multiple ? '确认' : false"
10
+ @confirm="onConfirm()"
11
+ >
12
+ <template #header>
13
+ <view :class="$style['PickerPopup--header']">
14
+ <view :class="$style['PickerPopup--title']">
15
+ <slot name="title">
16
+ <text>{{ title }}</text>
17
+ <text v-if="multiple">({{ tempCheckedCount }})</text>
18
+ <text :class="$style['PickerPopup--sub-title']">{{ subTitle }}</text>
19
+ </slot>
20
+ </view>
21
+ <view v-if="searchable" :class="$style['PickerPopup--search-wrapper']">
22
+ <!-- 搜索框 -->
23
+ <search-cpn
24
+ :placeholder="searchPlaceholder"
25
+ :class="$style['PickerPopup--search']"
26
+ @input-search="onFilter"
27
+ @search="onFilter"
28
+ @clear="onFilter"
29
+ >
30
+ </search-cpn>
31
+ </view>
32
+ </view>
33
+ </template>
34
+
35
+ <view
36
+ v-for="item in filteredList"
37
+ :key="item.option[valueKey]"
38
+ :class="[$style['PickerPopup--option'], { [$style['PickerPopup--checked']]: item.checked }]"
39
+ @click="checkPickerItem(item.option)"
40
+ >
41
+ <icon-cpn
42
+ v-if="multiple"
43
+ :icon="item.checked ? 'checkbox-checked' : 'checkbox-unchecked'"
44
+ :class="$style['PickerPopup--option-multi']"
45
+ />
46
+ <text :class="$style['PickerPopup--option-text']">{{ item.option[labelKey] }}</text>
47
+ <icon-cpn
48
+ v-if="!multiple && item.checked"
49
+ icon="radio-checked"
50
+ :class="$style['PickerPopup--option-single']"
51
+ />
52
+ </view>
53
+ <view v-if="pager && pager.data.length > 0" :class="$style['PickerPopup--load-more-wrapper']">
54
+ <load-more-cpn
55
+ :loading="pager.loadMoreTime !== 0"
56
+ :end="!pager.hasMore"
57
+ end-title="到底了"
58
+ @load-more="loadMore()"
59
+ />
60
+ </view>
61
+ <empty-cpn v-if="filteredList.length === 0" :class="$style['PickerPopup--empty']" />
62
+ </popup-content-cpn>
63
+ </template>
64
+ </popup-cpn>
65
+ </template>
66
+
67
+ <script>
68
+ import componentName from '../../mixins/componentName';
69
+ import EmptyCpn from '../empty/empty.vue';
70
+ import IconCpn from '../icon/icon.vue';
71
+ import LoadMoreCpn from '../load-more/load-more.vue';
72
+ import PopupCpn from '../popup/popup.vue';
73
+ import PopupContentCpn from '../popup/popup-content.vue';
74
+ import SearchCpn from '../search/search.vue';
75
+
76
+ export default {
77
+ name: 'AppPickerPopup',
78
+ options: {
79
+ virtualHost: true,
80
+ styleIsolation: 'shared',
81
+ },
82
+ components: { EmptyCpn, IconCpn, LoadMoreCpn, PopupCpn, PopupContentCpn, SearchCpn },
83
+ mixins: [componentName],
84
+ props: {
85
+ /** 是否可见 */
86
+ value: {
87
+ type: Boolean,
88
+ default: false,
89
+ },
90
+ /** 标题 */
91
+ title: {
92
+ type: String,
93
+ default: '',
94
+ },
95
+ /** 副标题 */
96
+ subTitle: {
97
+ type: String,
98
+ default: '',
99
+ },
100
+ /** 是否有筛选框 */
101
+ searchable: {
102
+ type: Boolean,
103
+ default: false,
104
+ },
105
+ /** 是否多选 */
106
+ multiple: {
107
+ type: Boolean,
108
+ default: false,
109
+ },
110
+ /** 搜索框占位文本 */
111
+ searchPlaceholder: {
112
+ type: String,
113
+ default: '请输入',
114
+ },
115
+ /** 选项 */
116
+ options: {
117
+ type: Array,
118
+ default: () => [],
119
+ },
120
+ /** 分页 */
121
+ pager: {
122
+ type: Object,
123
+ default: null,
124
+ },
125
+ /** 已选选项 */
126
+ checked: {
127
+ type: Array,
128
+ default: () => [],
129
+ },
130
+ /** 选项唯一标识 */
131
+ valueKey: {
132
+ type: String,
133
+ default: 'id',
134
+ },
135
+ /** 选项标签字段 */
136
+ labelKey: {
137
+ type: String,
138
+ default: 'label',
139
+ },
140
+ },
141
+ data() {
142
+ return {
143
+ /** 用于回到顶部 */
144
+ scrollTopValue: 0,
145
+ optionList: [],
146
+ tempCheckedMap: new Map(),
147
+ tempCheckedCount: 0,
148
+ filterText: '',
149
+ };
150
+ },
151
+ computed: {
152
+ filteredList() {
153
+ const text = this.filterText.trim();
154
+ return text ? this.optionList.filter((item) => item.option[this.labelKey].includes(text)) : this.optionList;
155
+ },
156
+ },
157
+ watch: {
158
+ options() {
159
+ this.setOptionList();
160
+ },
161
+ },
162
+ created() {
163
+ this.initPopup();
164
+ this.setOptionList();
165
+ },
166
+ methods: {
167
+ /** 初始化 */
168
+ initPopup() {
169
+ this.tempCheckedCount = this.checked.length;
170
+ this.checked.forEach((option) => {
171
+ this.tempCheckedMap.set(option[this.valueKey], option);
172
+ });
173
+ },
174
+ /** 格式化选项数据列表 */
175
+ setOptionList() {
176
+ this.optionList = this.options.map((option) => {
177
+ const checked = this.tempCheckedMap.has(option[this.valueKey]);
178
+ return { option, checked };
179
+ });
180
+ },
181
+ /** 勾选选项 */
182
+ checkPickerItem(option) {
183
+ const index = this.optionList.findIndex((item) => item.option[this.valueKey] === option[this.valueKey]);
184
+ if (index < 0) return;
185
+
186
+ if (!this.multiple) {
187
+ this.tempCheckedMap.clear();
188
+ this.tempCheckedMap.set(option[this.valueKey], option);
189
+ this.setOptionList();
190
+ this.$emit('confirm', option);
191
+ this.$refs.popup.close();
192
+ return;
193
+ }
194
+
195
+ this.optionList[index].checked = !this.optionList[index].checked;
196
+ if (this.optionList[index].checked) {
197
+ this.tempCheckedMap.set(option[this.valueKey], option);
198
+ } else {
199
+ this.tempCheckedMap.delete(option[this.valueKey]);
200
+ }
201
+ this.tempCheckedCount = this.tempCheckedMap.size;
202
+ },
203
+ /** 回到顶部 */
204
+ scrollTop() {
205
+ this.scrollTopValue = typeof this.scrollTopValue === 'number' ? '0px' : 0;
206
+ },
207
+ /** 过滤或搜索 */
208
+ onFilter(text) {
209
+ this.scrollTop();
210
+ if (this.pager) {
211
+ this.$emit('search', text);
212
+ return;
213
+ }
214
+ this.filterText = text;
215
+ },
216
+ /** 加载更多 */
217
+ loadMore() {
218
+ if (!this.pager) return;
219
+
220
+ this.$emit('load-more');
221
+ },
222
+ /** 点击确认按钮 */
223
+ onConfirm() {
224
+ this.$emit('confirm', this.tempCheckedMap.values().toArray());
225
+ this.$refs.popup.close();
226
+ },
227
+ },
228
+ };
229
+ </script>
230
+
231
+ <style lang="scss" module>
232
+ @use '../../styles/index' as *;
233
+
234
+ :host {
235
+ display: block;
236
+ }
237
+
238
+ .PickerPopup--header {
239
+ position: relative;
240
+ box-sizing: border-box;
241
+ height: UTILS__LOCAL_VAR(header-height);
242
+ padding: 20rpx 30rpx 0rpx;
243
+ display: flex;
244
+ align-items: center;
245
+ }
246
+ .PickerPopup--title {
247
+ flex: 1;
248
+ font-size: UTILS__GLOBAL_VAR(font-size, large);
249
+ font-weight: 600;
250
+ }
251
+ .PickerPopup--sub-title {
252
+ margin-left: 10rpx;
253
+ color: UTILS__GLOBAL_VAR(theme, placeholder);
254
+ font-size: UTILS__GLOBAL_VAR(font-size, normal);
255
+ font-weight: 400;
256
+ }
257
+ .PickerPopup--search-wrapper {
258
+ flex: none;
259
+ height: 88rpx;
260
+ display: flex;
261
+ align-items: center;
262
+ #{UTILS__VAR_NAME(height, search)}: 72rpx;
263
+ }
264
+ .PickerPopup--search {
265
+ flex: 1;
266
+ }
267
+
268
+ .PickerPopup--option {
269
+ display: flex;
270
+ justify-content: start;
271
+ align-items: center;
272
+ padding: 20rpx 0;
273
+ &.PickerPopup--checked {
274
+ color: UTILS__GLOBAL_VAR(theme, primary);
275
+ }
276
+ }
277
+ .PickerPopup--option-multi {
278
+ flex: none;
279
+ margin-right: 12rpx;
280
+ }
281
+ .PickerPopup--option-single {
282
+ flex: none;
283
+ margin-left: 12rpx;
284
+ }
285
+ .PickerPopup--option-text {
286
+ @include UTILS__ELLIPSIS();
287
+ }
288
+ .PickerPopup--empty {
289
+ margin: auto auto;
290
+ }
291
+ .PickerPopup--load-more-wrapper {
292
+ position: sticky;
293
+ top: 100%;
294
+ }
295
+ </style>