@ecolovo/uniapp-components 2.0.4 → 2.0.5
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.
- package/components/badge/badge.vue +22 -11
- package/components/badge/types.d.ts +6 -0
- package/components/badge/types.js +4 -0
- package/components/badge/types.ts +10 -0
- package/components/button/button.vue +77 -48
- package/components/button/types.d.ts +20 -0
- package/components/button/types.js +4 -0
- package/components/button/types.ts +24 -0
- package/components/checkbox/checkbox.scss +1 -1
- package/components/checkbox/checkbox.vue +2 -0
- package/components/checkbox/types.d.ts +10 -0
- package/components/checkbox/types.js +4 -0
- package/components/checkbox/types.ts +16 -0
- package/components/checkbox-group/checkbox-group.vue +2 -0
- package/components/checkbox-group/types.d.ts +10 -0
- package/components/checkbox-group/types.js +8 -0
- package/components/checkbox-group/types.ts +20 -0
- package/components/checkbox-group2/checkbox-group2.vue +2 -0
- package/components/data-list/data-list.vue +13 -7
- package/components/date-picker/date-picker.vue +2 -0
- package/components/date-picker/types.d.ts +12 -0
- package/components/date-picker/types.js +4 -0
- package/components/date-picker/types.ts +18 -0
- package/components/dialog/dialog-content.vue +61 -46
- package/components/dialog/dialog.vue +55 -29
- package/components/dialog/types.d.ts +20 -0
- package/components/dialog/types.js +4 -0
- package/components/dialog/types.ts +24 -0
- package/components/dropdown/dropdown.vue +2 -0
- package/components/dropdown/types.d.ts +10 -0
- package/components/dropdown/types.js +4 -0
- package/components/dropdown/types.ts +16 -0
- package/components/empty/empty.vue +37 -20
- package/components/empty/types.d.ts +12 -0
- package/components/empty/types.js +9 -0
- package/components/empty/types.ts +21 -0
- package/components/flex/flex.vue +2 -0
- package/components/flex/types.d.ts +12 -0
- package/components/flex/types.js +4 -0
- package/components/flex/types.ts +22 -0
- package/components/form/form.vue +2 -0
- package/components/form/types.d.ts +6 -0
- package/components/form/types.js +4 -0
- package/components/form/types.ts +10 -0
- package/components/form-item/form-item.scss +6 -0
- package/components/form-item/form-item.vue +9 -3
- package/components/form-item/types.d.ts +6 -0
- package/components/form-item/types.js +4 -0
- package/components/form-item/types.ts +12 -0
- package/components/image/image.vue +28 -21
- package/components/image/types.d.ts +18 -0
- package/components/image/types.js +4 -0
- package/components/image/types.ts +23 -0
- package/components/index.d.ts +1 -0
- package/components/index.js +1 -0
- package/components/index.ts +1 -0
- package/components/input/input.scss +9 -0
- package/components/input/input.vue +11 -4
- package/components/input/password-input.vue +3 -1
- package/components/input/types.d.ts +20 -0
- package/components/input/types.js +8 -0
- package/components/input/types.ts +31 -0
- package/components/list-page/list-page.vue +21 -24
- package/components/list-page/types.d.ts +6 -0
- package/components/list-page/types.js +4 -0
- package/components/list-page/types.ts +12 -0
- package/components/load-more/load-more.scss +1 -0
- package/components/load-more/load-more.vue +66 -6
- package/components/load-more/types.d.ts +6 -0
- package/components/load-more/types.js +4 -0
- package/components/load-more/types.ts +12 -0
- package/components/loading/loading.vue +2 -0
- package/components/loading/types.d.ts +6 -0
- package/components/loading/types.js +4 -0
- package/components/loading/types.ts +12 -0
- package/components/message-box/message-box.d.ts +14 -16
- package/components/message-box/message-box.ts +0 -2
- package/components/message-box/message-box.vue +18 -43
- package/components/message-box/types.d.ts +16 -0
- package/components/message-box/types.js +4 -0
- package/components/message-box/types.ts +22 -0
- package/components/number-dialog/number-dialog.vue +5 -3
- package/components/number-dialog/types.d.ts +18 -0
- package/components/number-dialog/types.js +4 -0
- package/components/number-dialog/types.ts +24 -0
- package/components/number-input/number-input.scss +1 -1
- package/components/number-input/number-input.vue +5 -3
- package/components/number-input/types.d.ts +20 -0
- package/components/number-input/types.js +4 -0
- package/components/number-input/types.ts +26 -0
- package/components/numpad/numpad.vue +2 -0
- package/components/numpad/types.d.ts +10 -0
- package/components/numpad/types.js +4 -0
- package/components/numpad/types.ts +14 -0
- package/components/page/page-body.scss +1 -1
- package/components/page/page-footer.vue +2 -3
- package/components/page/page-header.vue +19 -9
- package/components/page/page.vue +45 -14
- package/components/page/types.d.ts +16 -0
- package/components/page/types.js +8 -0
- package/components/page/types.ts +27 -0
- package/components/picker/picker-popup.vue +10 -6
- package/components/picker/picker.vue +8 -0
- package/components/picker/types.d.ts +14 -0
- package/components/picker/types.js +4 -0
- package/components/picker/types.ts +18 -0
- package/components/popover/popover-content.vue +10 -1
- package/components/popover/popover-mask.vue +5 -5
- package/components/popover/popover.vue +34 -29
- package/components/popover/types.d.ts +10 -0
- package/components/popover/types.js +4 -0
- package/components/popover/types.ts +16 -0
- package/components/popup/popup-content.vue +61 -43
- package/components/popup/popup.vue +34 -28
- package/components/popup/types.d.ts +20 -0
- package/components/popup/types.js +4 -0
- package/components/popup/types.ts +24 -0
- package/components/price/price.scss +7 -3
- package/components/price/price.vue +6 -0
- package/components/price/types.d.ts +10 -0
- package/components/price/types.js +4 -0
- package/components/price/types.ts +14 -0
- package/components/search/search.vue +2 -0
- package/components/search/types.d.ts +14 -0
- package/components/search/types.js +4 -0
- package/components/search/types.ts +18 -0
- package/components/searching/searching.vue +2 -0
- package/components/searching/types.d.ts +8 -0
- package/components/searching/types.js +4 -0
- package/components/searching/types.ts +14 -0
- package/components/switch/switch.vue +5 -8
- package/components/switch/types.d.ts +8 -0
- package/components/switch/types.js +4 -0
- package/components/switch/types.ts +12 -0
- package/components/tab/tab.vue +2 -0
- package/components/tab/types.d.ts +8 -0
- package/components/tab/types.js +4 -0
- package/components/tab/types.ts +12 -0
- package/components/textarea/textarea.scss +10 -0
- package/components/textarea/textarea.vue +17 -9
- package/components/textarea/types.d.ts +12 -0
- package/components/textarea/types.js +4 -0
- package/components/textarea/types.ts +18 -0
- package/components/upload/composable.d.ts +24 -0
- package/components/upload/composable.js +173 -0
- package/components/upload/composable.ts +228 -0
- package/components/upload/media-upload.scss +12 -0
- package/components/upload/media-upload.vue +250 -0
- package/components/upload/types.d.ts +29 -0
- package/components/upload/types.js +4 -0
- package/components/upload/types.ts +38 -0
- package/composable/component-name.d.ts +8 -0
- package/composable/component-name.js +11 -4
- package/composable/component-name.ts +8 -0
- package/composable/dialog.d.ts +40 -0
- package/composable/dialog.js +96 -0
- package/composable/dialog.ts +113 -0
- package/composable/index.d.ts +5 -0
- package/composable/index.js +5 -0
- package/composable/index.ts +5 -0
- package/composable/message-box.d.ts +45 -28
- package/composable/message-box.js +68 -53
- package/composable/message-box.ts +101 -36
- package/composable/model.d.ts +8 -0
- package/composable/model.js +23 -0
- package/composable/model.ts +27 -0
- package/composable/page.d.ts +41 -0
- package/composable/page.js +25 -0
- package/composable/page.ts +34 -0
- package/configs/index.d.ts +24 -19
- package/configs/index.js +38 -35
- package/configs/index.ts +19 -0
- package/easyCom.d.ts +6 -6
- package/easyCom.js +19 -31
- package/easyCom.ts +4 -4
- package/globals.d.ts +93 -33
- package/globals.js +1 -0
- package/globals.ts +118 -0
- package/index.d.ts +3 -2
- package/index.js +2 -2
- package/index.ts +3 -2
- package/init.d.ts +11 -6
- package/init.js +84 -14
- package/init.ts +86 -1
- package/package.json +9 -9
- package/styles/var/component.scss +1 -0
- package/utils/date.d.ts +14 -19
- package/utils/date.js +77 -87
- package/utils/freezeDeep.js +7 -7
- package/utils/price.d.ts +15 -18
- package/utils/price.js +36 -37
- package/utils/upload.d.ts +1 -0
- package/utils/upload.js +8 -0
- package/utils/upload.ts +12 -0
- package/utils/windowInfo.d.ts +1 -9
- package/utils/windowInfo.js +10 -17
- package/utils/round.d.ts +0 -2
- package/utils/round.js +0 -13
- package/utils/round.ts +0 -14
package/components/page/page.vue
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
<page-header-cpn
|
|
5
5
|
v-if="hasHeader"
|
|
6
6
|
fixed
|
|
7
|
+
:center="centerTitle"
|
|
7
8
|
:theme="theme"
|
|
8
9
|
:title="title"
|
|
10
|
+
:nav-type="isTabbar ? 0 : undefined"
|
|
9
11
|
>
|
|
10
|
-
<template #extra>
|
|
11
|
-
<slot name="header-extra"></slot>
|
|
12
|
-
</template>
|
|
12
|
+
<template #[extraSlot]><slot name="header-extra" /></template>
|
|
13
13
|
</page-header-cpn>
|
|
14
14
|
</slot>
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
:has-header="hasHeader"
|
|
20
20
|
:has-footer="hasFooter && !!$slots.footer"
|
|
21
21
|
:use-scroll="useScroll"
|
|
22
|
-
:is-tab-page="
|
|
22
|
+
:is-tab-page="isTabbar"
|
|
23
23
|
:enable-refresh="enableRefresh"
|
|
24
24
|
:refreshing="refreshing"
|
|
25
25
|
@scroll="$emit('scroll', $event)"
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
|
|
36
36
|
<page-footer-cpn
|
|
37
37
|
v-if="hasFooter && $slots.footer"
|
|
38
|
-
:is-tab-page="
|
|
38
|
+
:is-tab-page="isTabbar"
|
|
39
39
|
>
|
|
40
40
|
<slot name="footer"></slot>
|
|
41
41
|
</page-footer-cpn>
|
|
42
42
|
|
|
43
|
-
<message-box-cpn ref="
|
|
43
|
+
<message-box-cpn ref="messageBoxRef" />
|
|
44
44
|
|
|
45
45
|
<loading-cpn
|
|
46
46
|
v-if="loading"
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
52
|
<script lang="ts" setup>
|
|
53
|
-
import { computed, provide, ref } from 'vue';
|
|
53
|
+
import { computed, provide, ref, useSlots } from 'vue';
|
|
54
54
|
import useClassNames from '../../composable/component-name';
|
|
55
55
|
import LoadingCpn from '../loading/loading.vue';
|
|
56
56
|
import MessageBoxCpn from '../message-box/message-box.vue';
|
|
@@ -64,7 +64,9 @@ import {
|
|
|
64
64
|
navBarTopOffset,
|
|
65
65
|
safeAreaInsetBottom,
|
|
66
66
|
} from '../../utils/windowInfo';
|
|
67
|
-
import {
|
|
67
|
+
import { useMessageBoxComponent } from '../../composable/message-box';
|
|
68
|
+
import { pageProps } from './types';
|
|
69
|
+
import { useCurrentPageRoute } from '../../composable/page';
|
|
68
70
|
|
|
69
71
|
defineOptions({
|
|
70
72
|
options: {
|
|
@@ -75,9 +77,33 @@ defineOptions({
|
|
|
75
77
|
|
|
76
78
|
const classNames = useClassNames('page');
|
|
77
79
|
|
|
80
|
+
type _Slots = {
|
|
81
|
+
default: () => void;
|
|
82
|
+
/** 导航栏 */
|
|
83
|
+
header: () => void;
|
|
84
|
+
/** 导航栏额外内容 */
|
|
85
|
+
'header-extra': () => void;
|
|
86
|
+
/** 页面主体 */
|
|
87
|
+
body: () => void;
|
|
88
|
+
/** 固定布局内容插槽 */
|
|
89
|
+
fixed: () => void;
|
|
90
|
+
/** 底部操作栏 */
|
|
91
|
+
footer: () => void;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
defineSlots<_Slots>();
|
|
95
|
+
|
|
96
|
+
// 这些值用于插槽的透传
|
|
97
|
+
// 注意:小程序无法实现动态插槽,组件在初始化时就确定了哪些插槽在用,哪些没用使用
|
|
98
|
+
// 后续无论如何更新都无法改变这个行为,但插槽的内容可以动态更新
|
|
99
|
+
const $slots = useSlots();
|
|
100
|
+
const extraSlot = $slots['header-extra'] ? 'extra' : 'unused_slot';
|
|
101
|
+
|
|
78
102
|
type _Props = {
|
|
79
103
|
/** 页面标题 */
|
|
80
104
|
title?: string;
|
|
105
|
+
/** 导航栏标题是否居中显示 */
|
|
106
|
+
centerTitle?: boolean;
|
|
81
107
|
/** 页面是否有导航栏,当为 true 时,页面主体部分会为导航栏留出空间;否则内容部分会显示在屏幕顶部 */
|
|
82
108
|
hasHeader?: boolean;
|
|
83
109
|
/**
|
|
@@ -104,8 +130,9 @@ type _Props = {
|
|
|
104
130
|
tabbar?: boolean;
|
|
105
131
|
};
|
|
106
132
|
|
|
107
|
-
withDefaults(defineProps<_Props>(), {
|
|
133
|
+
const props = withDefaults(defineProps<_Props>(), {
|
|
108
134
|
title: '',
|
|
135
|
+
centerTitle: undefined,
|
|
109
136
|
hasHeader: true,
|
|
110
137
|
hasFooter: true,
|
|
111
138
|
useScroll: true,
|
|
@@ -115,9 +142,14 @@ withDefaults(defineProps<_Props>(), {
|
|
|
115
142
|
pageSize: 0,
|
|
116
143
|
showLoadMore: true,
|
|
117
144
|
theme: 'light',
|
|
118
|
-
tabbar:
|
|
145
|
+
tabbar: undefined,
|
|
146
|
+
...pageProps,
|
|
119
147
|
});
|
|
120
148
|
|
|
149
|
+
const { isTabbarPage } = useCurrentPageRoute();
|
|
150
|
+
|
|
151
|
+
const isTabbar = computed(() => props.tabbar ?? isTabbarPage.value);
|
|
152
|
+
|
|
121
153
|
defineEmits<{
|
|
122
154
|
(event: 'scroll', value: ScrollEvent): void;
|
|
123
155
|
(event: 'refresh'): void;
|
|
@@ -125,8 +157,9 @@ defineEmits<{
|
|
|
125
157
|
}>();
|
|
126
158
|
|
|
127
159
|
const pageBodyRef = ref<InstanceType<typeof PageBodyCpn>>();
|
|
128
|
-
const
|
|
129
|
-
|
|
160
|
+
const { messageBoxRef, show, showConfirm, showMessageBox } =
|
|
161
|
+
useMessageBoxComponent();
|
|
162
|
+
provide('ecolovo/page/messageBoxRef', messageBoxRef);
|
|
130
163
|
|
|
131
164
|
/**
|
|
132
165
|
* 滚动到顶部
|
|
@@ -146,8 +179,6 @@ const scrollIntoView = (viewId: string, animation = true) => {
|
|
|
146
179
|
pageBodyRef.value?.scrollIntoView(viewId, animation);
|
|
147
180
|
};
|
|
148
181
|
|
|
149
|
-
const { show, showConfirm, showMessageBox } = useMessageBox(pageMessageBoxRef);
|
|
150
|
-
|
|
151
182
|
const inlineStyle = computed(() => {
|
|
152
183
|
return [
|
|
153
184
|
// 顶部安全区高度
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ConfigurablePageProps = {
|
|
2
|
+
/** 是否使用scroll-view */
|
|
3
|
+
useScroll?: boolean;
|
|
4
|
+
/** 页面头部样式,主要用于控制导航栏字体颜色 */
|
|
5
|
+
theme?: 'light' | 'dark';
|
|
6
|
+
};
|
|
7
|
+
export declare let pageProps: ConfigurablePageProps;
|
|
8
|
+
export declare const setDefaultPageProps: (props?: ConfigurablePageProps) => void;
|
|
9
|
+
export type ConfigurablePageHeaderProps = {
|
|
10
|
+
/** 导航栏标题是否居中显示 */
|
|
11
|
+
center?: boolean;
|
|
12
|
+
/** 页面头部样式,主要用于控制导航栏字体颜色 */
|
|
13
|
+
theme?: 'light' | 'dark';
|
|
14
|
+
};
|
|
15
|
+
export declare let pageHeaderProps: ConfigurablePageHeaderProps;
|
|
16
|
+
export declare const setDefaultPageHeaderProps: (props?: ConfigurablePageHeaderProps) => void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type ConfigurablePageProps = {
|
|
2
|
+
/** 是否使用scroll-view */
|
|
3
|
+
useScroll?: boolean;
|
|
4
|
+
/** 页面头部样式,主要用于控制导航栏字体颜色 */
|
|
5
|
+
theme?: 'light' | 'dark';
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export let pageProps: ConfigurablePageProps = {};
|
|
9
|
+
|
|
10
|
+
export const setDefaultPageProps = (props: ConfigurablePageProps = {}) => {
|
|
11
|
+
pageProps = props;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ConfigurablePageHeaderProps = {
|
|
15
|
+
/** 导航栏标题是否居中显示 */
|
|
16
|
+
center?: boolean;
|
|
17
|
+
/** 页面头部样式,主要用于控制导航栏字体颜色 */
|
|
18
|
+
theme?: 'light' | 'dark';
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export let pageHeaderProps: ConfigurablePageHeaderProps = {};
|
|
22
|
+
|
|
23
|
+
export const setDefaultPageHeaderProps = (
|
|
24
|
+
props: ConfigurablePageHeaderProps = {}
|
|
25
|
+
) => {
|
|
26
|
+
pageHeaderProps = props;
|
|
27
|
+
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<popup-cpn
|
|
3
3
|
ref="popupRef"
|
|
4
|
-
|
|
4
|
+
v-model="isShow"
|
|
5
5
|
:class="[...classNames, $style['PickerPopup']]"
|
|
6
|
-
@update:model-value="emit('update:modelValue', $event)"
|
|
7
6
|
>
|
|
8
7
|
<template #content>
|
|
9
8
|
<popup-content-cpn
|
|
@@ -112,11 +111,18 @@ defineOptions({
|
|
|
112
111
|
|
|
113
112
|
const classNames = useClassNames('picker-popup');
|
|
114
113
|
|
|
114
|
+
type _Slots = {
|
|
115
|
+
title: () => void;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
defineSlots<_Slots>();
|
|
119
|
+
|
|
120
|
+
/** 是否可见 */
|
|
121
|
+
const isShow = defineModel<boolean>();
|
|
122
|
+
|
|
115
123
|
type _Option = Record<string, string | number>;
|
|
116
124
|
|
|
117
125
|
type _Props = {
|
|
118
|
-
/** 是否可见 */
|
|
119
|
-
modelValue?: boolean;
|
|
120
126
|
/** 标题 */
|
|
121
127
|
title?: string;
|
|
122
128
|
/** 副标题 */
|
|
@@ -142,7 +148,6 @@ type _Props = {
|
|
|
142
148
|
};
|
|
143
149
|
|
|
144
150
|
const props = withDefaults(defineProps<_Props>(), {
|
|
145
|
-
modelValue: false,
|
|
146
151
|
title: '',
|
|
147
152
|
subTitle: '',
|
|
148
153
|
searchable: false,
|
|
@@ -157,7 +162,6 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
157
162
|
});
|
|
158
163
|
|
|
159
164
|
const emit = defineEmits<{
|
|
160
|
-
(e: 'update:modelValue', val: boolean): void;
|
|
161
165
|
(e: 'confirm', val: _Option | _Option[]): void;
|
|
162
166
|
(e: 'search', text: string): void;
|
|
163
167
|
(e: 'load-more'): void;
|
|
@@ -30,6 +30,7 @@ import { computed, inject, ref } from 'vue';
|
|
|
30
30
|
import useClassNames from '../../composable/component-name';
|
|
31
31
|
import SelectorCpn from '../selector/selector.vue';
|
|
32
32
|
import PickerPopupCpn from './picker-popup.vue';
|
|
33
|
+
import { pickerProps } from './types';
|
|
33
34
|
|
|
34
35
|
defineOptions({
|
|
35
36
|
options: {
|
|
@@ -40,6 +41,12 @@ defineOptions({
|
|
|
40
41
|
|
|
41
42
|
const classNames = useClassNames('picker');
|
|
42
43
|
|
|
44
|
+
type _Slots = {
|
|
45
|
+
popup: () => void;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
defineSlots<_Slots>();
|
|
49
|
+
|
|
43
50
|
type _Option = Record<string, string | number>;
|
|
44
51
|
type _Value = string | number | boolean | Record<string, unknown>;
|
|
45
52
|
|
|
@@ -80,6 +87,7 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
80
87
|
options: () => [],
|
|
81
88
|
multiple: false,
|
|
82
89
|
joinText: '、',
|
|
90
|
+
...pickerProps,
|
|
83
91
|
});
|
|
84
92
|
|
|
85
93
|
const emit = defineEmits<{
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ConfigurablePickerProps = {
|
|
2
|
+
/** 选项唯一标识 */
|
|
3
|
+
valueKey?: string;
|
|
4
|
+
/** 选项标签字段 */
|
|
5
|
+
labelKey?: string;
|
|
6
|
+
/** 占位文本 */
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
/** 弹出框标题 */
|
|
9
|
+
popupTitle?: string;
|
|
10
|
+
/** 多选时选项拼接的分隔符 */
|
|
11
|
+
joinText?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare let pickerProps: ConfigurablePickerProps;
|
|
14
|
+
export declare const setDefaultPickerProps: (props?: ConfigurablePickerProps) => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ConfigurablePickerProps = {
|
|
2
|
+
/** 选项唯一标识 */
|
|
3
|
+
valueKey?: string;
|
|
4
|
+
/** 选项标签字段 */
|
|
5
|
+
labelKey?: string;
|
|
6
|
+
/** 占位文本 */
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
/** 弹出框标题 */
|
|
9
|
+
popupTitle?: string;
|
|
10
|
+
/** 多选时选项拼接的分隔符 */
|
|
11
|
+
joinText?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export let pickerProps: ConfigurablePickerProps = {};
|
|
15
|
+
|
|
16
|
+
export const setDefaultPickerProps = (props: ConfigurablePickerProps = {}) => {
|
|
17
|
+
pickerProps = props;
|
|
18
|
+
};
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
<!-- loading 动画 -->
|
|
36
36
|
<view v-if="loading" :class="$style['PopoverContent--loading']">
|
|
37
|
-
<icon-cpn icon="loading-dot-spinner"></icon-cpn>
|
|
37
|
+
<icon-cpn icon="loading-dot-spinner" spinning></icon-cpn>
|
|
38
38
|
</view>
|
|
39
39
|
</view>
|
|
40
40
|
</template>
|
|
@@ -57,6 +57,15 @@ defineOptions({
|
|
|
57
57
|
|
|
58
58
|
const classNames = useClassNames('popover-content');
|
|
59
59
|
|
|
60
|
+
type _Slots = {
|
|
61
|
+
custom: () => void;
|
|
62
|
+
header: () => void;
|
|
63
|
+
default: () => void;
|
|
64
|
+
footer: () => void;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
defineSlots<_Slots>();
|
|
68
|
+
|
|
60
69
|
type _Props = {
|
|
61
70
|
/** 弹出框位置,可选值为 top、bottom、left、right、center */
|
|
62
71
|
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
@@ -33,20 +33,19 @@ defineOptions({
|
|
|
33
33
|
|
|
34
34
|
const classNames = useClassNames('popover-mask');
|
|
35
35
|
|
|
36
|
+
const isShow = defineModel<boolean>({ required: true });
|
|
37
|
+
|
|
36
38
|
type _Props = {
|
|
37
|
-
/** v-model 绑定值,控制弹出框是否可见 */
|
|
38
|
-
modelValue?: boolean;
|
|
39
39
|
/** 是否模态弹出框 */
|
|
40
40
|
modal?: boolean;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
const props = withDefaults(defineProps<_Props>(), {
|
|
44
|
-
modelValue: false,
|
|
45
44
|
modal: false,
|
|
46
45
|
});
|
|
47
46
|
|
|
48
47
|
const emit = defineEmits<{
|
|
49
|
-
(e: '
|
|
48
|
+
(e: 'mask'): void;
|
|
50
49
|
(e: 'close'): void;
|
|
51
50
|
(e: 'closed'): void;
|
|
52
51
|
}>();
|
|
@@ -70,7 +69,7 @@ const close = (onClosed?: VoidFunction) => {
|
|
|
70
69
|
|
|
71
70
|
setTimeout(() => {
|
|
72
71
|
onClosed?.();
|
|
73
|
-
|
|
72
|
+
isShow.value = false;
|
|
74
73
|
emit('closed');
|
|
75
74
|
}, 300);
|
|
76
75
|
};
|
|
@@ -78,6 +77,7 @@ const close = (onClosed?: VoidFunction) => {
|
|
|
78
77
|
/** 点击遮罩层 */
|
|
79
78
|
const onMask = () => {
|
|
80
79
|
if (props.modal) return;
|
|
80
|
+
emit('mask');
|
|
81
81
|
close();
|
|
82
82
|
};
|
|
83
83
|
|
|
@@ -1,49 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view :class="[...classNames, $style['Popover']]">
|
|
2
|
+
<view v-if="isShow" :class="[...classNames, $style['Popover']]">
|
|
3
3
|
<popover-mask-cpn
|
|
4
|
-
v-if="modelValue"
|
|
5
4
|
ref="maskRef"
|
|
6
|
-
|
|
5
|
+
v-model="isShow"
|
|
7
6
|
:modal="modal || loading"
|
|
8
|
-
@
|
|
7
|
+
@mask="onConfirm()"
|
|
9
8
|
@close="$emit('close')"
|
|
10
9
|
@closed="$emit('closed')"
|
|
11
10
|
>
|
|
12
11
|
<popover-content-cpn
|
|
13
|
-
v-if="$slots.custom"
|
|
14
12
|
:position="position"
|
|
15
13
|
:fullscreen="fullscreen"
|
|
16
14
|
:loading="loading"
|
|
17
15
|
>
|
|
18
|
-
<template #custom>
|
|
19
|
-
|
|
20
|
-
</template>
|
|
21
|
-
</popover-content-cpn>
|
|
22
|
-
<popover-content-cpn
|
|
23
|
-
v-else
|
|
24
|
-
:position="position"
|
|
25
|
-
:fullscreen="fullscreen"
|
|
26
|
-
:loading="loading"
|
|
27
|
-
>
|
|
28
|
-
<template v-if="$slots.header" #header>
|
|
29
|
-
<slot name="header"></slot>
|
|
30
|
-
</template>
|
|
31
|
-
|
|
16
|
+
<template #[customSlot]><slot name="custom" /></template>
|
|
17
|
+
<template #[headerSlot]><slot name="header" /></template>
|
|
32
18
|
<slot></slot>
|
|
33
|
-
|
|
34
|
-
<template v-if="$slots.footer" #footer>
|
|
35
|
-
<slot name="footer"></slot>
|
|
36
|
-
</template>
|
|
19
|
+
<template #[footerSlot]><slot name="footer" /></template>
|
|
37
20
|
</popover-content-cpn>
|
|
38
21
|
</popover-mask-cpn>
|
|
39
22
|
</view>
|
|
40
23
|
</template>
|
|
41
24
|
|
|
42
25
|
<script lang="ts" setup>
|
|
43
|
-
import { ref } from 'vue';
|
|
26
|
+
import { ref, useSlots } from 'vue';
|
|
44
27
|
import useClassNames from '../../composable/component-name';
|
|
45
28
|
import PopoverContentCpn from './popover-content.vue';
|
|
46
29
|
import PopoverMaskCpn from './popover-mask.vue';
|
|
30
|
+
import { popoverProps } from './types';
|
|
31
|
+
import { useAwaitableDialog, useModelValue } from '../../composable';
|
|
47
32
|
|
|
48
33
|
defineOptions({
|
|
49
34
|
options: {
|
|
@@ -54,9 +39,30 @@ defineOptions({
|
|
|
54
39
|
|
|
55
40
|
const classNames = useClassNames('popover');
|
|
56
41
|
|
|
42
|
+
type _Slots = {
|
|
43
|
+
custom: () => void;
|
|
44
|
+
header: () => void;
|
|
45
|
+
default: () => void;
|
|
46
|
+
footer: () => void;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
defineSlots<_Slots>();
|
|
50
|
+
|
|
51
|
+
// 这些值用于插槽的透传
|
|
52
|
+
// 注意:小程序无法实现动态插槽,组件在初始化时就确定了哪些插槽在用,哪些没用使用
|
|
53
|
+
// 后续无论如何更新都无法改变这个行为,但插槽的内容可以动态更新
|
|
54
|
+
const $slots = useSlots();
|
|
55
|
+
const customSlot = $slots.custom ? 'custom' : 'unused_slot';
|
|
56
|
+
const headerSlot = $slots.header ? 'header' : 'unused_slot';
|
|
57
|
+
const footerSlot = $slots.footer ? 'footer' : 'unused_slot';
|
|
58
|
+
|
|
59
|
+
const isShow_ = defineModel<boolean>();
|
|
60
|
+
/** 是否可见 */
|
|
61
|
+
const isShow = useModelValue(isShow_);
|
|
62
|
+
|
|
63
|
+
const { show, onConfirm } = useAwaitableDialog(isShow);
|
|
64
|
+
|
|
57
65
|
type _Props = {
|
|
58
|
-
/** v-model 绑定值,控制弹出框是否可见 */
|
|
59
|
-
modelValue?: boolean;
|
|
60
66
|
/** 弹出框位置,可选值为 top、bottom、left、right、center */
|
|
61
67
|
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
62
68
|
/** 是否占满屏幕 */
|
|
@@ -68,15 +74,14 @@ type _Props = {
|
|
|
68
74
|
};
|
|
69
75
|
|
|
70
76
|
withDefaults(defineProps<_Props>(), {
|
|
71
|
-
modelValue: false,
|
|
72
77
|
position: 'bottom',
|
|
73
78
|
fullscreen: false,
|
|
74
79
|
modal: false,
|
|
75
80
|
loading: false,
|
|
81
|
+
...popoverProps,
|
|
76
82
|
});
|
|
77
83
|
|
|
78
84
|
defineEmits<{
|
|
79
|
-
(e: 'update:modelValue', val: boolean): void;
|
|
80
85
|
(e: 'close'): void;
|
|
81
86
|
(e: 'closed'): void;
|
|
82
87
|
}>();
|
|
@@ -88,7 +93,7 @@ const close = (onClosed?: VoidFunction) => {
|
|
|
88
93
|
maskRef.value?.close(onClosed);
|
|
89
94
|
};
|
|
90
95
|
|
|
91
|
-
defineExpose({ close });
|
|
96
|
+
defineExpose({ show, close });
|
|
92
97
|
</script>
|
|
93
98
|
|
|
94
99
|
<style lang="scss" module>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ConfigurablePopoverProps = {
|
|
2
|
+
/** 弹出框位置,可选值为 top、bottom、left、right、center */
|
|
3
|
+
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
4
|
+
/** 是否占满屏幕 */
|
|
5
|
+
fullscreen?: boolean;
|
|
6
|
+
/** 是否模态弹出框 */
|
|
7
|
+
modal?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare let popoverProps: ConfigurablePopoverProps;
|
|
10
|
+
export declare const setDefaultPopoverProps: (props?: ConfigurablePopoverProps) => void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ConfigurablePopoverProps = {
|
|
2
|
+
/** 弹出框位置,可选值为 top、bottom、left、right、center */
|
|
3
|
+
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
4
|
+
/** 是否占满屏幕 */
|
|
5
|
+
fullscreen?: boolean;
|
|
6
|
+
/** 是否模态弹出框 */
|
|
7
|
+
modal?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export let popoverProps: ConfigurablePopoverProps = {};
|
|
11
|
+
|
|
12
|
+
export const setDefaultPopoverProps = (
|
|
13
|
+
props: ConfigurablePopoverProps = {}
|
|
14
|
+
) => {
|
|
15
|
+
popoverProps = props;
|
|
16
|
+
};
|
|
@@ -3,32 +3,33 @@
|
|
|
3
3
|
<popover-content-cpn position="bottom" :loading="loading">
|
|
4
4
|
<!-- 内容上方标题 -->
|
|
5
5
|
<template #header>
|
|
6
|
-
<slot
|
|
7
|
-
<view
|
|
8
|
-
v-else-if="title || showClose"
|
|
9
|
-
:class="$style['PopupContent--header']"
|
|
10
|
-
>
|
|
6
|
+
<slot name="header">
|
|
11
7
|
<view
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
[$style['PopupContent--title-center']]:
|
|
16
|
-
centerTitle,
|
|
17
|
-
},
|
|
18
|
-
]"
|
|
8
|
+
v-if="title || showClose"
|
|
9
|
+
:class="$style['PopupContent--header']"
|
|
19
10
|
>
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
<view
|
|
12
|
+
:class="[
|
|
13
|
+
$style['PopupContent--title'],
|
|
14
|
+
{
|
|
15
|
+
[$style['PopupContent--title-center']]:
|
|
16
|
+
centerTitle,
|
|
17
|
+
},
|
|
18
|
+
]"
|
|
19
|
+
>
|
|
20
|
+
<slot name="title">
|
|
21
|
+
<text>{{ title }}</text>
|
|
22
|
+
</slot>
|
|
23
|
+
</view>
|
|
24
|
+
<view
|
|
25
|
+
v-if="showClose"
|
|
26
|
+
:class="$style['PopupContent--close']"
|
|
27
|
+
@click="$emit('close')"
|
|
28
|
+
>
|
|
29
|
+
<icon-cpn icon="close" tap-size="80rpx" />
|
|
30
|
+
</view>
|
|
23
31
|
</view>
|
|
24
|
-
|
|
25
|
-
v-if="showClose"
|
|
26
|
-
:class="$style['PopupContent--close']"
|
|
27
|
-
@click="$emit('close')"
|
|
28
|
-
>
|
|
29
|
-
<icon-cpn icon="close" tap-size="80rpx" />
|
|
30
|
-
</view>
|
|
31
|
-
</view>
|
|
32
|
+
</slot>
|
|
32
33
|
</template>
|
|
33
34
|
|
|
34
35
|
<!-- 内容区域 -->
|
|
@@ -36,29 +37,35 @@
|
|
|
36
37
|
|
|
37
38
|
<!-- 内容下方操作按钮 -->
|
|
38
39
|
<template #footer>
|
|
39
|
-
<slot
|
|
40
|
-
<view
|
|
41
|
-
v-else-if="cancel || confirm"
|
|
42
|
-
:class="$style['PopupContent--footer']"
|
|
43
|
-
>
|
|
44
|
-
<view v-if="cancel" :class="$style['PopupContent--button']">
|
|
45
|
-
<slot name="cancel">
|
|
46
|
-
<button-cpn plain @click="$emit('cancel')">
|
|
47
|
-
{{ cancel }}
|
|
48
|
-
</button-cpn>
|
|
49
|
-
</slot>
|
|
50
|
-
</view>
|
|
40
|
+
<slot name="footer">
|
|
51
41
|
<view
|
|
52
|
-
v-if="
|
|
53
|
-
|
|
42
|
+
v-if="
|
|
43
|
+
cancel || confirm || $slots.cancel || $slots.confirm
|
|
44
|
+
"
|
|
45
|
+
:class="$style['PopupContent--footer']"
|
|
54
46
|
>
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
<view
|
|
48
|
+
v-if="cancel || $slots.cancel"
|
|
49
|
+
:class="$style['PopupContent--button']"
|
|
50
|
+
>
|
|
51
|
+
<slot name="cancel">
|
|
52
|
+
<button-cpn plain @click="$emit('cancel')">
|
|
53
|
+
{{ cancel }}
|
|
54
|
+
</button-cpn>
|
|
55
|
+
</slot>
|
|
56
|
+
</view>
|
|
57
|
+
<view
|
|
58
|
+
v-if="confirm || $slots.confirm"
|
|
59
|
+
:class="$style['PopupContent--button']"
|
|
60
|
+
>
|
|
61
|
+
<slot name="confirm">
|
|
62
|
+
<button-cpn @click="$emit('confirm')">
|
|
63
|
+
{{ confirm }}
|
|
64
|
+
</button-cpn>
|
|
65
|
+
</slot>
|
|
66
|
+
</view>
|
|
60
67
|
</view>
|
|
61
|
-
</
|
|
68
|
+
</slot>
|
|
62
69
|
</template>
|
|
63
70
|
</popover-content-cpn>
|
|
64
71
|
</view>
|
|
@@ -79,6 +86,17 @@ defineOptions({
|
|
|
79
86
|
|
|
80
87
|
const classNames = useClassNames('popup-content');
|
|
81
88
|
|
|
89
|
+
type _Slots = {
|
|
90
|
+
header: () => void;
|
|
91
|
+
title: () => void;
|
|
92
|
+
default: () => void;
|
|
93
|
+
footer: () => void;
|
|
94
|
+
cancel: () => void;
|
|
95
|
+
confirm: () => void;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
defineSlots<_Slots>();
|
|
99
|
+
|
|
82
100
|
type _Props = {
|
|
83
101
|
/** 是否显示 loading 动画 */
|
|
84
102
|
loading?: boolean;
|