@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,151 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <selector-cpn
4
+ :value="valueStr"
5
+ :readonly="isReadonly"
6
+ :disabled="disabled"
7
+ :placeholder="placeholder"
8
+ @click="showPicker"
9
+ />
10
+
11
+ <slot name="popup">
12
+ <picker-popup-cpn
13
+ v-if="isPickerVisible"
14
+ v-model="isPickerVisible"
15
+ :title="popupTitle"
16
+ :options="options"
17
+ :multiple="multiple"
18
+ :checked="checkedOptions"
19
+ :value-key="valueKey"
20
+ :label-key="labelKey"
21
+ @confirm="onConfirm"
22
+ />
23
+ </slot>
24
+ </view>
25
+ </template>
26
+
27
+ <script>
28
+ import isEqual from 'lodash-es/isEqual';
29
+ import componentName from '../../mixins/componentName';
30
+ import { isFormReadonly } from '../form/mixin';
31
+ import SelectorCpn from '../selector/selector.vue';
32
+ import PickerPopupCpn from './picker-popup.vue';
33
+
34
+ export default {
35
+ name: 'AppPicker',
36
+ options: {
37
+ virtualHost: true,
38
+ styleIsolation: 'shared',
39
+ },
40
+ components: { SelectorCpn, PickerPopupCpn },
41
+ mixins: [componentName, isFormReadonly],
42
+ props: {
43
+ /** 绑定值 */
44
+ value: {
45
+ type: [String, Number, Boolean, Object, Array],
46
+ default: null,
47
+ },
48
+ /** 绑定值文本 */
49
+ valueText: {
50
+ type: String,
51
+ default: '',
52
+ },
53
+ /** 选项唯一标识 */
54
+ valueKey: {
55
+ type: String,
56
+ default: 'id',
57
+ },
58
+ /** 选项标签字段 */
59
+ labelKey: {
60
+ type: String,
61
+ default: 'label',
62
+ },
63
+ /** 是否禁用 */
64
+ disabled: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ /** 是否只读 */
69
+ readonly: {
70
+ type: Boolean,
71
+ default: false,
72
+ },
73
+ /** 占位文本 */
74
+ placeholder: {
75
+ type: String,
76
+ default: '请选择',
77
+ },
78
+ /** 弹出框标题 */
79
+ popupTitle: {
80
+ type: String,
81
+ default: '请选择',
82
+ },
83
+ /** 选项 */
84
+ options: {
85
+ type: Array,
86
+ default: () => [],
87
+ },
88
+ /** 是否多选 */
89
+ multiple: {
90
+ type: Boolean,
91
+ default: false,
92
+ },
93
+ /** 多选时选项拼接的分隔符 */
94
+ joinText: {
95
+ type: String,
96
+ default: '、',
97
+ },
98
+ },
99
+ data() {
100
+ return {
101
+ /** 选择框是否可见 */
102
+ isPickerVisible: false,
103
+ };
104
+ },
105
+ computed: {
106
+ isReadonly() {
107
+ return this.readonly || this.isFormReadonly;
108
+ },
109
+ checkedOptions() {
110
+ if (this.multiple) {
111
+ return this.options.filter((item) => this.value.includes(item[this.valueKey]));
112
+ }
113
+ return this.options.filter((item) => item[this.valueKey] === this.value);
114
+ },
115
+ valueStr() {
116
+ if (this.valueText) return this.valueText;
117
+ if (this.value === null) return '';
118
+ return this.checkedOptions.map((item) => item[this.labelKey]).join(this.joinText);
119
+ },
120
+ },
121
+ methods: {
122
+ showPicker() {
123
+ if (this.disabled || this.isReadonly) {
124
+ return;
125
+ }
126
+
127
+ this.isPickerVisible = true;
128
+ this.$emit('show');
129
+ },
130
+
131
+ onConfirm(checked) {
132
+ const checkedValue = this.multiple ? checked.map((item) => item[this.valueKey]) : checked[this.valueKey];
133
+
134
+ this.$emit('input', checkedValue);
135
+ this.$emit('pick', checked);
136
+
137
+ if (isEqual(checkedValue, this.value)) return;
138
+ this.$emit('change', checkedValue, checked);
139
+ },
140
+ },
141
+ };
142
+ </script>
143
+
144
+ <style lang="scss" module>
145
+ @use '../../styles/index' as *;
146
+
147
+ .Picker {
148
+ width: 100%;
149
+ height: 100%;
150
+ }
151
+ </style>
@@ -0,0 +1,255 @@
1
+ <template>
2
+ <view
3
+ :class="[
4
+ componentClassNames,
5
+ $style['PopoverContent--at-' + usingPosition],
6
+ {
7
+ [$style['PopoverContent--fullscreen']]: fullscreen,
8
+ [$style['PopoverContent--content-initialized']]: initialized,
9
+ },
10
+ ]"
11
+ :style="styleStr"
12
+ >
13
+ <slot name="custom">
14
+ <!-- 使用自定义插槽时需要注意内容部分的尺寸,太长的内容需要手动添加 scroll-view 包裹 -->
15
+ <view :class="$style['PopoverContent--content']">
16
+ <!-- header 插槽 -->
17
+ <slot name="header"></slot>
18
+
19
+ <scroll-view :class="$style['PopoverContent--body-scroll']" scroll-y="true">
20
+ <view :class="$style['PopoverContent--body']">
21
+ <!-- 默认插槽 -->
22
+ <slot></slot>
23
+ </view>
24
+ </scroll-view>
25
+
26
+ <!-- footer 插槽 -->
27
+ <slot name="footer"></slot>
28
+ </view>
29
+ </slot>
30
+
31
+ <!-- loading 动画 -->
32
+ <view v-if="loading" :class="$style['PopoverContent--loading']">
33
+ <icon-cpn icon="loading-dot-spinner"></icon-cpn>
34
+ </view>
35
+ </view>
36
+ </template>
37
+
38
+ <script>
39
+ import componentName from '../../mixins/componentName';
40
+ import windowInfoMixin from '../../mixins/windowInfo';
41
+ import IconCpn from '../icon/icon.vue';
42
+
43
+ export default {
44
+ name: 'AppPopoverContent',
45
+ options: {
46
+ virtualHost: true,
47
+ styleIsolation: 'shared',
48
+ },
49
+ components: { IconCpn },
50
+ mixins: [componentName, windowInfoMixin],
51
+ props: {
52
+ /** 弹出框位置,可选值为 top、bottom、left、right、center */
53
+ position: {
54
+ type: String,
55
+ default: 'bottom',
56
+ },
57
+ /** 是否占满屏幕 */
58
+ fullscreen: {
59
+ type: Boolean,
60
+ default: false,
61
+ },
62
+ /** 是否显示 loading 动画 */
63
+ loading: {
64
+ type: Boolean,
65
+ default: false,
66
+ },
67
+ },
68
+ data() {
69
+ return {
70
+ /**
71
+ * 弹出框是否已初始化
72
+ * - 由于计算属性 usingPosition 在模拟器上会使动画显示不正常(计算属性计算滞后),
73
+ * 故添加此标识在初始化完成前不作任何动画
74
+ */
75
+ initialized: false,
76
+ };
77
+ },
78
+ computed: {
79
+ /** 计算后的位置值 */
80
+ usingPosition() {
81
+ return ['top', 'bottom', 'left', 'right', 'center'].includes(this.position) ? this.position : 'bottom';
82
+ },
83
+ styleStr() {
84
+ return [
85
+ `--header-bar-bottom: ${this.navBarBottomOffset}px;`,
86
+ `--safe-area-bottom: ${this.safeAreaInsetBottom}px;`,
87
+ ].join(' ');
88
+ },
89
+ },
90
+ mounted() {
91
+ this.$nextTick(() => {
92
+ this.initialized = true;
93
+ });
94
+ },
95
+ };
96
+ </script>
97
+
98
+ <style lang="scss" module>
99
+ @use '../../styles/index' as *;
100
+
101
+ // 定义外部变量
102
+ $component-name: 'popover';
103
+ $component-vars: $popover;
104
+ %external-vars {
105
+ @include UTILS__DEFINE_COMPONENT_VARS();
106
+ }
107
+
108
+ :host {
109
+ display: block;
110
+ }
111
+
112
+ .PopoverContent {
113
+ @extend %external-vars;
114
+ position: absolute;
115
+ opacity: 1;
116
+ --appear-transform: translate(0, 0) scale(1);
117
+
118
+ // 区别各个方向的动画效果和位置
119
+ &.PopoverContent--at-top {
120
+ top: 0;
121
+ left: 0;
122
+ width: 100%;
123
+ min-height: UTILS__LOCAL_VAR(min-height);
124
+ max-height: UTILS__LOCAL_VAR(max-height);
125
+ transform: translate(0, -100%) scale(1);
126
+ --content-radius: 0 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)};
127
+ --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
128
+ }
129
+ &.PopoverContent--at-bottom {
130
+ bottom: 0;
131
+ left: 0;
132
+ width: 100%;
133
+ min-height: UTILS__LOCAL_VAR(min-height);
134
+ max-height: UTILS__LOCAL_VAR(max-height);
135
+ transform: translate(0, 100%) scale(1);
136
+ --content-radius: #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)} 0 0;
137
+ --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
138
+ }
139
+ &.PopoverContent--at-left {
140
+ top: 0;
141
+ left: 0;
142
+ width: UTILS__LOCAL_VAR(width);
143
+ height: 100%;
144
+ transform: translate(-100%, 0) scale(1);
145
+ --content-radius: 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)} 0;
146
+ --scroll-max-height: 100vh;
147
+ }
148
+ &.PopoverContent--at-right {
149
+ top: 0;
150
+ right: 0;
151
+ width: UTILS__LOCAL_VAR(width);
152
+ height: 100%;
153
+ transform: translate(100%, 0) scale(1);
154
+ --content-radius: #{UTILS__LOCAL_VAR(radius)} 0 0 #{UTILS__LOCAL_VAR(radius)};
155
+ --scroll-max-height: 100vh;
156
+ }
157
+ &.PopoverContent--at-center {
158
+ inset: UTILS__LOCAL_VAR(position);
159
+ width: UTILS__LOCAL_VAR(width);
160
+ min-height: UTILS__LOCAL_VAR(min-height);
161
+ max-height: UTILS__LOCAL_VAR(max-height);
162
+ opacity: 0;
163
+ transform: translate(-50%, -50%) scale(0.8);
164
+ --appear-transform: translate(-50%, -50%) scale(1);
165
+ --content-radius: #{UTILS__LOCAL_VAR(radius)};
166
+ --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
167
+ }
168
+ &.PopoverContent--fullscreen {
169
+ width: 100vw;
170
+ height: 100vh;
171
+ max-height: 100vh;
172
+ --content-radius: 0;
173
+ --scroll-max-height: 100vh;
174
+ }
175
+
176
+ // 内容部分显示动画
177
+ &.PopoverContent--content-initialized {
178
+ transition: transform 0.3s, opacity 0.3s;
179
+ }
180
+ :global(.PopoverMask--visible) &.PopoverContent--content-initialized {
181
+ opacity: 1;
182
+ transform: var(--appear-transform);
183
+ }
184
+
185
+ .PopoverContent--content {
186
+ background: UTILS__LOCAL_VAR(background);
187
+ border-radius: var(--content-radius, #{UTILS__LOCAL_VAR(radius)});
188
+ // 宽度占满
189
+ @at-root %full-width #{UTILS__LAST_SELECTOR(&)} {
190
+ width: 100%;
191
+ }
192
+ // 高度占满
193
+ @at-root %full-height #{UTILS__LAST_SELECTOR(&)} {
194
+ height: 100%;
195
+ }
196
+ // 顶部安全区域
197
+ @at-root %safe-top #{UTILS__LAST_SELECTOR(&)} {
198
+ padding-top: var(--header-bar-bottom);
199
+ --safe-top-padding: var(--header-bar-bottom);
200
+ }
201
+ // 底部安全区域
202
+ @at-root %safe-bottom #{UTILS__LAST_SELECTOR(&)} {
203
+ padding-bottom: var(--safe-area-bottom);
204
+ --safe-bottom-padding: var(--safe-area-bottom);
205
+ }
206
+ // 不需要安全区域
207
+ @at-root %no-safe-area #{UTILS__LAST_SELECTOR(&)} {
208
+ --safe-top-padding: 0px;
209
+ --safe-bottom-padding: 0px;
210
+ }
211
+ }
212
+ &.PopoverContent--at-center:not(.PopoverContent--fullscreen) {
213
+ @extend %no-safe-area;
214
+ }
215
+ &.PopoverContent--at-top {
216
+ @extend %full-width;
217
+ @extend %safe-top;
218
+ }
219
+ &.PopoverContent--at-bottom {
220
+ @extend %full-width;
221
+ @extend %safe-bottom;
222
+ }
223
+ &.PopoverContent--at-left,
224
+ &.PopoverContent--at-right,
225
+ &.PopoverContent--fullscreen {
226
+ @extend %full-height;
227
+ @extend %safe-top;
228
+ @extend %safe-bottom;
229
+ }
230
+
231
+ // scroll-view
232
+ .PopoverContent--body-scroll {
233
+ $header-padding: calc(var(--safe-top-padding, 0px) + #{UTILS__LOCAL_VAR(header-height)});
234
+ $footer-padding: calc(var(--safe-bottom-padding, 0px) + #{UTILS__LOCAL_VAR(footer-height)});
235
+ min-height: max(calc(#{UTILS__LOCAL_VAR(min-height)} - #{$header-padding} - #{$footer-padding}), 0px);
236
+ max-height: calc(var(--scroll-max-height) - #{$header-padding} - #{$footer-padding});
237
+ }
238
+
239
+ .PopoverContent--body {
240
+ padding: UTILS__LOCAL_VAR(padding);
241
+ }
242
+
243
+ .PopoverContent--loading {
244
+ position: absolute;
245
+ inset: 0;
246
+ border-radius: var(--content-radius);
247
+ color: #999;
248
+ background: #ffffff80;
249
+ display: flex;
250
+ justify-content: center;
251
+ align-items: center;
252
+ font-size: 60rpx;
253
+ }
254
+ }
255
+ </style>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <view
3
+ :class="[
4
+ componentClassNames,
5
+ { [$style['PopoverMask--visible']]: isVisible, 'PopoverMask--visible': isVisible },
6
+ ]"
7
+ @touchmove.stop.prevent="doNothing"
8
+ >
9
+ <!-- 遮罩层 -->
10
+ <view
11
+ :class="[$style['PopoverMask--mask'], { [$style['PopoverMask--animated']]: isInitialized }]"
12
+ @click="onMask()"
13
+ ></view>
14
+
15
+ <slot></slot>
16
+ </view>
17
+ </template>
18
+
19
+ <script>
20
+ import componentName from '../../mixins/componentName';
21
+
22
+ export default {
23
+ name: 'AppPopoverMask',
24
+ options: {
25
+ virtualHost: true,
26
+ styleIsolation: 'shared',
27
+ },
28
+ mixins: [componentName],
29
+ props: {
30
+ /** v-model 绑定值,控制弹出框是否可见 */
31
+ value: {
32
+ type: Boolean,
33
+ default: false,
34
+ },
35
+ /** 是否模态弹出框 */
36
+ modal: {
37
+ type: Boolean,
38
+ default: false,
39
+ },
40
+ },
41
+ data() {
42
+ return {
43
+ /** 弹出框是否可见 */
44
+ isVisible: false,
45
+ /** 控制是否有动画,其实没必要,只是在模拟器上显示不正常 */
46
+ isInitialized: false,
47
+ };
48
+ },
49
+ mounted() {
50
+ this.$nextTick(() => {
51
+ this.isVisible = true;
52
+ this.isInitialized = true;
53
+ });
54
+ },
55
+ methods: {
56
+ doNothing() {},
57
+ /** 点击遮罩层 */
58
+ onMask() {
59
+ if (this.modal) return;
60
+
61
+ this.close();
62
+ },
63
+ /** 关闭弹出框 */
64
+ close(onClosed) {
65
+ this.$emit('close');
66
+ this.isVisible = false;
67
+
68
+ setTimeout(() => {
69
+ onClosed?.();
70
+ this.$emit('input', false);
71
+ this.$emit('closed');
72
+ }, 300);
73
+ },
74
+ },
75
+ };
76
+ </script>
77
+
78
+ <style lang="scss" module>
79
+ @use '../../styles/index' as *;
80
+
81
+ // 定义外部变量
82
+ $component-name: 'popover';
83
+ $component-vars: $popover;
84
+ %external-vars {
85
+ @include UTILS__DEFINE_COMPONENT_VARS();
86
+ }
87
+
88
+ :host {
89
+ display: block;
90
+ }
91
+
92
+ .PopoverMask {
93
+ @extend %external-vars;
94
+ position: fixed;
95
+ inset: 0;
96
+ z-index: UTILS__z-index();
97
+
98
+ // 遮罩层
99
+ .PopoverMask--mask {
100
+ position: absolute;
101
+ inset: 0;
102
+ background-color: UTILS__LOCAL_VAR(mask-color);
103
+ opacity: 0;
104
+ &.PopoverMask--animated {
105
+ transition: opacity 0.3s;
106
+ }
107
+ }
108
+ &.PopoverMask--visible .PopoverMask--mask {
109
+ transition: opacity 0.3s;
110
+ opacity: 1;
111
+ }
112
+ }
113
+ </style>
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <popover-mask-cpn
4
+ v-if="value"
5
+ ref="mask"
6
+ :value="value"
7
+ :modal="modal || loading"
8
+ @input="$emit('input', $event)"
9
+ @close="$emit('close')"
10
+ @closed="$emit('closed')"
11
+ >
12
+ <popover-content-cpn v-if="$slots.custom" :position="position" :fullscreen="fullscreen" :loading="loading">
13
+ <template #custom>
14
+ <slot name="custom"></slot>
15
+ </template>
16
+ </popover-content-cpn>
17
+ <popover-content-cpn v-else :position="position" :fullscreen="fullscreen" :loading="loading">
18
+ <template v-if="$slots.header" #header>
19
+ <slot name="header"></slot>
20
+ </template>
21
+
22
+ <slot></slot>
23
+
24
+ <template v-if="$slots.footer" #footer>
25
+ <slot name="footer"></slot>
26
+ </template>
27
+ </popover-content-cpn>
28
+ </popover-mask-cpn>
29
+ </view>
30
+ </template>
31
+
32
+ <script>
33
+ import componentName from '../../mixins/componentName';
34
+ import windowInfoMixin from '../../mixins/windowInfo';
35
+ import popoverContentCpn from './popover-content.vue';
36
+ import popoverMaskCpn from './popover-mask.vue';
37
+
38
+ export default {
39
+ name: 'AppPopover',
40
+ options: {
41
+ virtualHost: true,
42
+ styleIsolation: 'shared',
43
+ },
44
+ components: { popoverContentCpn, popoverMaskCpn },
45
+ mixins: [componentName, windowInfoMixin],
46
+ props: {
47
+ /** v-model 绑定值,控制弹出框是否可见 */
48
+ value: {
49
+ type: Boolean,
50
+ default: false,
51
+ },
52
+ /** 弹出框位置,可选值为 top、bottom、left、right、center */
53
+ position: {
54
+ type: String,
55
+ default: 'bottom',
56
+ },
57
+ /** 是否占满屏幕 */
58
+ fullscreen: {
59
+ type: Boolean,
60
+ default: false,
61
+ },
62
+ /** 是否模态弹出框 */
63
+ modal: {
64
+ type: Boolean,
65
+ default: false,
66
+ },
67
+ /** 是否显示 loading 动画 */
68
+ loading: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ },
73
+ methods: {
74
+ /** 关闭弹出框 */
75
+ close(onClosed) {
76
+ this.$refs.mask.close(onClosed);
77
+ },
78
+ },
79
+ };
80
+ </script>
81
+
82
+ <style lang="scss" module>
83
+ @use '../../styles/index' as *;
84
+ </style>