@xiaohaih/json-form-vant 0.0.1
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/CHANGELOG.md +9 -0
- package/README.md +807 -0
- package/TODO.md +36 -0
- package/components/area/index.ts +6 -0
- package/components/area/index.vue +120 -0
- package/components/area/types.ts +84 -0
- package/components/cascader/index.ts +6 -0
- package/components/cascader/index.vue +146 -0
- package/components/cascader/types.ts +75 -0
- package/components/checkbox/index.ts +6 -0
- package/components/checkbox/index.vue +59 -0
- package/components/checkbox/types.ts +54 -0
- package/components/checkbox-group/index.ts +6 -0
- package/components/checkbox-group/index.vue +67 -0
- package/components/checkbox-group/types.ts +63 -0
- package/components/component-definition/components.ts +29 -0
- package/components/component-definition/definition.ts +25 -0
- package/components/component-definition/index.ts +4 -0
- package/components/custom-render/index.ts +6 -0
- package/components/custom-render/index.vue +66 -0
- package/components/custom-render/types.ts +43 -0
- package/components/date-picker/index.ts +6 -0
- package/components/date-picker/index.vue +130 -0
- package/components/date-picker/types.ts +91 -0
- package/components/date-time-picker-group/index.ts +6 -0
- package/components/date-time-picker-group/index.vue +158 -0
- package/components/date-time-picker-group/types.ts +115 -0
- package/components/datetime-picker/index.ts +6 -0
- package/components/datetime-picker/index.vue +128 -0
- package/components/datetime-picker/types.ts +78 -0
- package/components/dynamic-group/index.ts +10 -0
- package/components/dynamic-group/index.vue +140 -0
- package/components/dynamic-group/types.ts +68 -0
- package/components/group/assist.ts +99 -0
- package/components/group/index.ts +7 -0
- package/components/group/index.vue +117 -0
- package/components/group/types.ts +57 -0
- package/components/group/virtual-group.vue +38 -0
- package/components/index.ts +10 -0
- package/components/input/index.ts +6 -0
- package/components/input/index.vue +83 -0
- package/components/input/types.ts +43 -0
- package/components/input-slot/index.ts +6 -0
- package/components/input-slot/index.vue +148 -0
- package/components/input-slot/types.ts +34 -0
- package/components/number-keyboard/index.ts +6 -0
- package/components/number-keyboard/index.vue +81 -0
- package/components/number-keyboard/types.ts +57 -0
- package/components/password-input/index.ts +6 -0
- package/components/password-input/index.vue +103 -0
- package/components/password-input/types.ts +64 -0
- package/components/picker/index.ts +6 -0
- package/components/picker/index.vue +136 -0
- package/components/picker/types.ts +94 -0
- package/components/radio/index.ts +6 -0
- package/components/radio/index.vue +68 -0
- package/components/radio/types.ts +58 -0
- package/components/radio-group/index.ts +6 -0
- package/components/radio-group/index.vue +74 -0
- package/components/radio-group/types.ts +65 -0
- package/components/rate/index.ts +6 -0
- package/components/rate/index.vue +63 -0
- package/components/rate/types.ts +47 -0
- package/components/share.ts +78 -0
- package/components/signature/index.ts +6 -0
- package/components/signature/index.vue +65 -0
- package/components/signature/instance.vue +161 -0
- package/components/signature/types.ts +79 -0
- package/components/slider/index.ts +6 -0
- package/components/slider/index.vue +63 -0
- package/components/slider/types.ts +53 -0
- package/components/stepper/index.ts +6 -0
- package/components/stepper/index.vue +62 -0
- package/components/stepper/types.ts +47 -0
- package/components/switch/index.ts +6 -0
- package/components/switch/index.vue +61 -0
- package/components/switch/types.ts +51 -0
- package/components/time-picker/index.ts +6 -0
- package/components/time-picker/index.vue +130 -0
- package/components/time-picker/types.ts +91 -0
- package/components/tree-select/index.ts +6 -0
- package/components/tree-select/index.vue +160 -0
- package/components/tree-select/types.ts +77 -0
- package/components/upload/index.ts +6 -0
- package/components/upload/index.vue +109 -0
- package/components/upload/types.ts +85 -0
- package/components/use.ts +45 -0
- package/components/utils.ts +52 -0
- package/components/wrapper/index.ts +6 -0
- package/components/wrapper/index.vue +117 -0
- package/components/wrapper/types.ts +94 -0
- package/dist/components/area/index.d.ts +5 -0
- package/dist/components/area/index.vue.d.ts +1843 -0
- package/dist/components/area/types.d.ts +1434 -0
- package/dist/components/cascader/index.d.ts +5 -0
- package/dist/components/cascader/index.vue.d.ts +2467 -0
- package/dist/components/cascader/types.d.ts +1419 -0
- package/dist/components/checkbox/index.d.ts +5 -0
- package/dist/components/checkbox/index.vue.d.ts +1550 -0
- package/dist/components/checkbox/types.d.ts +1313 -0
- package/dist/components/checkbox-group/index.d.ts +5 -0
- package/dist/components/checkbox-group/index.vue.d.ts +1643 -0
- package/dist/components/checkbox-group/types.d.ts +1372 -0
- package/dist/components/component-definition/components.d.ts +30 -0
- package/dist/components/component-definition/index.d.ts +4 -0
- package/dist/components/custom-render/index.d.ts +5 -0
- package/dist/components/custom-render/index.vue.d.ts +1473 -0
- package/dist/components/custom-render/types.d.ts +1175 -0
- package/dist/components/date-picker/index.d.ts +5 -0
- package/dist/components/date-picker/index.vue.d.ts +1888 -0
- package/dist/components/date-picker/types.d.ts +1458 -0
- package/dist/components/date-time-picker-group/index.d.ts +5 -0
- package/dist/components/date-time-picker-group/index.vue.d.ts +2181 -0
- package/dist/components/date-time-picker-group/types.d.ts +1549 -0
- package/dist/components/dynamic-group/index.d.ts +5 -0
- package/dist/components/dynamic-group/index.vue.d.ts +457 -0
- package/dist/components/dynamic-group/types.d.ts +403 -0
- package/dist/components/group/assist.d.ts +58 -0
- package/dist/components/group/index.d.ts +6 -0
- package/dist/components/group/index.vue.d.ts +139 -0
- package/dist/components/group/types.d.ts +189 -0
- package/dist/components/group/virtual-group.vue.d.ts +42 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/input/index.d.ts +5 -0
- package/dist/components/input/index.vue.d.ts +2229 -0
- package/dist/components/input/types.d.ts +1258 -0
- package/dist/components/input-slot/index.d.ts +5 -0
- package/dist/components/input-slot/index.vue.d.ts +626 -0
- package/dist/components/input-slot/types.d.ts +311 -0
- package/dist/components/number-keyboard/index.d.ts +5 -0
- package/dist/components/number-keyboard/index.vue.d.ts +1643 -0
- package/dist/components/number-keyboard/types.d.ts +1324 -0
- package/dist/components/password-input/index.d.ts +5 -0
- package/dist/components/password-input/index.vue.d.ts +1715 -0
- package/dist/components/password-input/types.d.ts +1357 -0
- package/dist/components/picker/index.d.ts +5 -0
- package/dist/components/picker/index.vue.d.ts +1868 -0
- package/dist/components/picker/types.d.ts +1466 -0
- package/dist/components/radio/index.d.ts +5 -0
- package/dist/components/radio/index.vue.d.ts +1563 -0
- package/dist/components/radio/types.d.ts +1327 -0
- package/dist/components/radio-group/index.d.ts +5 -0
- package/dist/components/radio-group/index.vue.d.ts +1617 -0
- package/dist/components/radio-group/types.d.ts +1383 -0
- package/dist/components/rate/index.d.ts +5 -0
- package/dist/components/rate/index.vue.d.ts +1557 -0
- package/dist/components/rate/types.d.ts +1281 -0
- package/dist/components/share.d.ts +679 -0
- package/dist/components/signature/index.d.ts +5 -0
- package/dist/components/signature/index.vue.d.ts +3017 -0
- package/dist/components/signature/instance.vue.d.ts +1614 -0
- package/dist/components/signature/types.d.ts +1369 -0
- package/dist/components/slider/index.d.ts +5 -0
- package/dist/components/slider/index.vue.d.ts +1563 -0
- package/dist/components/slider/types.d.ts +1302 -0
- package/dist/components/stepper/index.d.ts +5 -0
- package/dist/components/stepper/index.vue.d.ts +1620 -0
- package/dist/components/stepper/types.d.ts +1281 -0
- package/dist/components/switch/index.d.ts +5 -0
- package/dist/components/switch/index.vue.d.ts +1529 -0
- package/dist/components/switch/types.d.ts +1296 -0
- package/dist/components/time-picker/index.d.ts +5 -0
- package/dist/components/time-picker/index.vue.d.ts +1936 -0
- package/dist/components/time-picker/types.d.ts +1458 -0
- package/dist/components/tree-select/index.d.ts +5 -0
- package/dist/components/tree-select/index.vue.d.ts +1802 -0
- package/dist/components/tree-select/types.d.ts +1411 -0
- package/dist/components/upload/index.d.ts +5 -0
- package/dist/components/upload/index.vue.d.ts +1697 -0
- package/dist/components/upload/types.d.ts +1376 -0
- package/dist/components/use.d.ts +53 -0
- package/dist/components/utils.d.ts +15 -0
- package/dist/components/wrapper/index.d.ts +5 -0
- package/dist/components/wrapper/index.vue.d.ts +1085 -0
- package/dist/components/wrapper/types.d.ts +541 -0
- package/dist/docs/.vitepress/config.d.ts +3 -0
- package/dist/docs/.vitepress/theme/index.d.ts +2 -0
- package/dist/index.cjs.js +5459 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.cjs.min.js +3568 -0
- package/dist/index.cjs.min.js.map +1 -0
- package/dist/index.esm.js +5264 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.esm.min.js +3559 -0
- package/dist/index.esm.min.js.map +1 -0
- package/dist/index.umd.js +5465 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/index.umd.min.js +3573 -0
- package/dist/index.umd.min.js.map +1 -0
- package/dist/src/assist.d.ts +32 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/interface.d.ts +129 -0
- package/dist/src/utils.d.ts +9 -0
- package/dist/src/version.d.ts +2 -0
- package/docs/.vitepress/config.ts +99 -0
- package/docs/.vitepress/theme/index.ts +5 -0
- package/docs/README.md +20 -0
- package/docs/index.md +25 -0
- package/env.d.ts +8 -0
- package/package.json +71 -0
- package/scripts/generate-version.mjs +26 -0
- package/scripts/postinstall.cjs +13 -0
- package/scripts/utils.cjs +67 -0
- package/src/assist.ts +40 -0
- package/src/index.ts +5 -0
- package/src/interface.ts +293 -0
- package/src/utils.ts +22 -0
- package/src/version.ts +2 -0
- package/tsconfig.app.json +41 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +24 -0
- package/tsdown.config.ts +12 -0
- package/vite.config.ts +93 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<VanField
|
|
3
|
+
v-if="!hide"
|
|
4
|
+
:name="field"
|
|
5
|
+
:disabled="globalDisabled || disabled"
|
|
6
|
+
:readonly="true"
|
|
7
|
+
:is-link="isLink"
|
|
8
|
+
:model-value="showText"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
@click="clickHandle"
|
|
11
|
+
>
|
|
12
|
+
<template #extra>
|
|
13
|
+
<VanPopup v-model:show="popupInfo.visible" teleport="body" round position="bottom" v-bind="popupProps" v-on="popupOn" @close="popupInfo.close">
|
|
14
|
+
<VanTimePicker
|
|
15
|
+
:model-value="checkedArr"
|
|
16
|
+
v-bind="timePickerProps" v-on="timePickerOn"
|
|
17
|
+
@change="changeHandle" @confirm="confirmHandle" @cancel="cancelHandle"
|
|
18
|
+
>
|
|
19
|
+
<template v-for="(item, slotName) of timePickerSlots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
20
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" />
|
|
21
|
+
</template>
|
|
22
|
+
</VanTimePicker>
|
|
23
|
+
</VanPopup>
|
|
24
|
+
</template>
|
|
25
|
+
<template v-for="(item, slotName) of slots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
26
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" />
|
|
27
|
+
</template>
|
|
28
|
+
</VanField>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts">
|
|
32
|
+
import { getNode, hyphenate, usePlain } from '@xiaohaih/json-form-core';
|
|
33
|
+
import { Field as VanField, Popup as VanPopup, TimePicker as VanTimePicker } from 'vant';
|
|
34
|
+
import type { SlotsType } from 'vue';
|
|
35
|
+
import { computed, defineComponent, nextTick, ref, watch } from 'vue';
|
|
36
|
+
import type { PickerOption } from '../picker/types';
|
|
37
|
+
import { useCommonSetup } from '../use';
|
|
38
|
+
import type { TimePickerSlots } from './types';
|
|
39
|
+
import { timePickerEmitsPrivate as emits, timePickerPropsPrivate as props } from './types';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @file 时间选择框
|
|
43
|
+
*/
|
|
44
|
+
export default defineComponent({
|
|
45
|
+
name: 'HTimePicker',
|
|
46
|
+
components: { VanField, VanPopup, VanTimePicker },
|
|
47
|
+
inheritAttrs: false,
|
|
48
|
+
props,
|
|
49
|
+
emits,
|
|
50
|
+
slots: Object as SlotsType<TimePickerSlots>,
|
|
51
|
+
setup(props, ctx) {
|
|
52
|
+
const plain = usePlain(props);
|
|
53
|
+
const { slotProps } = useCommonSetup(props, ctx, plain);
|
|
54
|
+
/** 展示在页面上的值 */
|
|
55
|
+
const showText = ref('');
|
|
56
|
+
/** 给时间组件的值 */
|
|
57
|
+
const checkedArr = ref<string[]>([]);
|
|
58
|
+
let tempValue: any;
|
|
59
|
+
// 监听外部值的改变, 如果改变且与临时值不一致时
|
|
60
|
+
// 则更新当前值, 并重置临时值
|
|
61
|
+
watch(
|
|
62
|
+
plain.checked,
|
|
63
|
+
(val) => {
|
|
64
|
+
if (val === tempValue) return tempValue = null;
|
|
65
|
+
tempValue = null;
|
|
66
|
+
checkedArr.value = val ? props.valueUnformat(val, props.separator) : [];
|
|
67
|
+
showText.value = checkedArr.value.length ? props.format(checkedArr.value, props.separator) : '';
|
|
68
|
+
},
|
|
69
|
+
{ immediate: true },
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
/** 点击事件 */
|
|
73
|
+
function clickHandle(ev: MouseEvent) {
|
|
74
|
+
if (plain.globalDisabled.value || props.disabled || plain.globalReadonly.value || props.readonly) return;
|
|
75
|
+
props.onRowClick ? props.onRowClick(popupInfo.value, ev) : popupInfo.value.open();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 时间更改事件
|
|
79
|
+
* @param {string} type 事件类型
|
|
80
|
+
* @param {string} value 日期值
|
|
81
|
+
*/
|
|
82
|
+
function timeEventHandle(type: string, value: PickerOption) {
|
|
83
|
+
if (props.valueTrigger === type || props.timePickerProps?.showToolbar === false) {
|
|
84
|
+
checkedArr.value = value.selectedValues;
|
|
85
|
+
plain.change(props.valueFormat(value.selectedValues, props.separator));
|
|
86
|
+
showText.value = props.format(value.selectedValues, props.separator);
|
|
87
|
+
tempValue = plain.checked.value;
|
|
88
|
+
nextTick(() => tempValue = null);
|
|
89
|
+
}
|
|
90
|
+
switch (type) {
|
|
91
|
+
case 'confirm':
|
|
92
|
+
case 'cancel':
|
|
93
|
+
{
|
|
94
|
+
popupInfo.value.close();
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
default: break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** 弹窗显示状态 */
|
|
102
|
+
const popupInfo = ref({
|
|
103
|
+
visible: false,
|
|
104
|
+
open() {
|
|
105
|
+
popupInfo.value.visible = true;
|
|
106
|
+
},
|
|
107
|
+
close() {
|
|
108
|
+
popupInfo.value.visible = false;
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
hyphenate,
|
|
114
|
+
getNode,
|
|
115
|
+
...plain,
|
|
116
|
+
slotProps,
|
|
117
|
+
showText,
|
|
118
|
+
checkedArr,
|
|
119
|
+
clickHandle,
|
|
120
|
+
changeHandle: timeEventHandle.bind(null, 'change'),
|
|
121
|
+
confirmHandle: timeEventHandle.bind(null, 'confirm'),
|
|
122
|
+
cancelHandle: timeEventHandle.bind(null, 'cancel'),
|
|
123
|
+
popupInfo,
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<style lang="scss" scoped>
|
|
130
|
+
</style>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { emits2obj, PlainProps } from '@xiaohaih/json-form-core';
|
|
2
|
+
import { emits2props, plainProps } from '@xiaohaih/json-form-core';
|
|
3
|
+
import type { Popup as VanPopup } from 'vant';
|
|
4
|
+
import { Field as VanField, TimePicker as VanTimePicker } from 'vant';
|
|
5
|
+
import type { ExtractPublicPropTypes, PropType } from 'vue';
|
|
6
|
+
import type { ComponentEmit, ComponentExposed, ComponentProps } from 'vue-component-type-helpers';
|
|
7
|
+
import type { PickerOption } from '../picker/types';
|
|
8
|
+
import type { CommonProps, CommonSlots, CommonSlotsProps, ComponentType } from '../share';
|
|
9
|
+
import { commonProps } from '../share';
|
|
10
|
+
|
|
11
|
+
/** 组件传参 - 私有 */
|
|
12
|
+
export function timePickerPropsGeneric<Query extends Record<string, any>, OptionQuery extends Record<string, any>>() {
|
|
13
|
+
return {
|
|
14
|
+
...commonProps as CommonProps<Query, OptionQuery>,
|
|
15
|
+
...plainProps as PlainProps<Query, OptionQuery>,
|
|
16
|
+
/** VanTimePicker 组件的属性 */
|
|
17
|
+
timePickerProps: { type: Object as PropType<Partial<ComponentProps<typeof VanTimePicker>>> },
|
|
18
|
+
/** VanTimePicker 组件的事件 - 兼容 vue2 版本 */
|
|
19
|
+
timePickerOn: { type: Object as PropType<Partial<ReturnType<typeof emits2obj<NonNullable<typeof VanTimePicker.emits>>>>>, default: () => ({}) },
|
|
20
|
+
/** VanTimePicker 组件的插槽 */
|
|
21
|
+
timePickerSlots: { type: Object as PropType<{
|
|
22
|
+
/** 自定义整个顶部栏的内容 */
|
|
23
|
+
toolbar?: ComponentType<CommonSlotsProps<any, any>>;
|
|
24
|
+
/** 自定义标题内容 */
|
|
25
|
+
title?: ComponentType<CommonSlotsProps<any, any>>;
|
|
26
|
+
/** 自定义确认按钮内容 */
|
|
27
|
+
confirm?: ComponentType<CommonSlotsProps<any, any>>;
|
|
28
|
+
/** 自定义取消按钮内容 */
|
|
29
|
+
cancel?: ComponentType<CommonSlotsProps<any, any>>;
|
|
30
|
+
/** 自定义选项内容 */
|
|
31
|
+
option?: ComponentType<{ option: PickerOption; index: number } & CommonSlotsProps<any, any>>;
|
|
32
|
+
/** 自定义选项上方内容 */
|
|
33
|
+
columnsTop?: ComponentType<CommonSlotsProps<any, any>>;
|
|
34
|
+
/** 自定义选项下方内容 */
|
|
35
|
+
columnsBottom?: ComponentType<CommonSlotsProps<any, any>>;
|
|
36
|
+
}> },
|
|
37
|
+
/** 是否展示右侧箭头并开启点击反馈 - Field 字段, 调整默认值 */
|
|
38
|
+
isLink: { type: Boolean, default: true },
|
|
39
|
+
/** 点击事件, 当传递了此事件时, 会忽略内部打开弹窗操作 */
|
|
40
|
+
onRowClick: { type: Function as PropType<(option: { open: () => void; close: () => void }, ev: MouseEvent) => void> },
|
|
41
|
+
/** 日期分隔符 @default : */
|
|
42
|
+
separator: { type: String, default: ':' },
|
|
43
|
+
/** 对值进行格式化 - 显示在页面上的值 */
|
|
44
|
+
format: { type: Function as PropType<(option: string[], separator: string) => any>, default: valueFormatDefault },
|
|
45
|
+
/** 对值进行格式化 - 提交值 */
|
|
46
|
+
valueFormat: { type: Function as PropType<(option: string[], separator: string) => any>, default: valueFormatDefault },
|
|
47
|
+
/** 取消值的格式化 - 给 VanDatePicker 的值 */
|
|
48
|
+
valueUnformat: { type: Function as PropType<(option: any, separator: string) => string[]>, default: valueUnformatDefault },
|
|
49
|
+
/** 值触发方式 @default confirm */
|
|
50
|
+
valueTrigger: { type: String as PropType<'change' | 'confirm' | 'cancel'>, default: 'confirm' },
|
|
51
|
+
/** 弹窗组件的属性 */
|
|
52
|
+
popupProps: { type: Object as PropType<Partial<ComponentExposed<typeof VanPopup>>> },
|
|
53
|
+
/** 弹窗组件的事件 - 兼容 vue2 版本 */
|
|
54
|
+
popupOn: { type: Object as PropType<Partial<ReturnType<typeof emits2obj<NonNullable<typeof VanPopup.emits>>>>>, default: () => ({}) },
|
|
55
|
+
} as const;
|
|
56
|
+
}
|
|
57
|
+
/** 组件传参 - 私有 */
|
|
58
|
+
export const timePickerPropsPrivate = timePickerPropsGeneric();
|
|
59
|
+
/** 组件传参 - 外部调用 */
|
|
60
|
+
export const timePickerProps = {
|
|
61
|
+
...VanField.props as unknown as {},
|
|
62
|
+
...timePickerPropsPrivate,
|
|
63
|
+
};
|
|
64
|
+
export type TimePickerProps<Query extends Record<string, any>, OptionQuery extends Record<string, any>> = ExtractPublicPropTypes<ReturnType<typeof timePickerPropsGeneric<Query, OptionQuery>>>;
|
|
65
|
+
|
|
66
|
+
/** 组件事件 - 私有 */
|
|
67
|
+
export function timePickerEmitsGeneric<T>() {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
/** 组件事件 - 私有 */
|
|
71
|
+
export const timePickerEmitsPrivate = timePickerEmitsGeneric();
|
|
72
|
+
/** 组件事件 - 外部调用 */
|
|
73
|
+
export const timePickerEmits = {
|
|
74
|
+
...VanField.emits,
|
|
75
|
+
...timePickerEmitsPrivate,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type TimePickerEmits<T> = ReturnType<typeof timePickerEmitsGeneric<T>>;
|
|
79
|
+
|
|
80
|
+
export interface TimePickerSlots extends CommonSlots<any> {
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** 默认的合并函数 */
|
|
84
|
+
function valueFormatDefault(option: string[], separator: string) {
|
|
85
|
+
return option.join(separator);
|
|
86
|
+
}
|
|
87
|
+
/** 默认的取消格式化函数 */
|
|
88
|
+
function valueUnformatDefault(val: string, separator: string) {
|
|
89
|
+
if (!val) return [];
|
|
90
|
+
return Array.isArray(val) ? val : val.split(separator);
|
|
91
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<VanField
|
|
3
|
+
v-if="!hide"
|
|
4
|
+
:name="field"
|
|
5
|
+
:disabled="globalDisabled || disabled"
|
|
6
|
+
:readonly="true"
|
|
7
|
+
:is-link="isLink"
|
|
8
|
+
:model-value="showText"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
@click="clickHandle"
|
|
11
|
+
>
|
|
12
|
+
<template #extra>
|
|
13
|
+
<VanPopup v-model:show="popupInfo.visible" teleport="body" round position="bottom" v-bind="popupProps" v-on="popupOn" @close="popupInfo.close">
|
|
14
|
+
<VanTreeSelect
|
|
15
|
+
:main-active-index="mainActiveIndex"
|
|
16
|
+
:active-id="checked"
|
|
17
|
+
:items="finalOption"
|
|
18
|
+
v-bind="treeSelectProps" v-on="treeSelectOn"
|
|
19
|
+
@update:main-active-index="mainActiveIndexChange"
|
|
20
|
+
@update:active-id="activeIdChange"
|
|
21
|
+
>
|
|
22
|
+
<template v-for="(item, slotName) of treeSelectSlots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
23
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" :options="finalOption" />
|
|
24
|
+
</template>
|
|
25
|
+
</VanTreeSelect>
|
|
26
|
+
</VanPopup>
|
|
27
|
+
</template>
|
|
28
|
+
<template v-for="(item, slotName) of slots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
29
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" />
|
|
30
|
+
</template>
|
|
31
|
+
</VanField>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import { getNode, hyphenate, usePlain } from '@xiaohaih/json-form-core';
|
|
36
|
+
import { Field as VanField, Popup as VanPopup, TreeSelect as VanTreeSelect } from 'vant';
|
|
37
|
+
import type { SlotsType } from 'vue';
|
|
38
|
+
import { computed, defineComponent, nextTick, ref, watch } from 'vue';
|
|
39
|
+
import type { PickerOption } from '../picker/types';
|
|
40
|
+
import { useCommonSetup } from '../use';
|
|
41
|
+
import type { TreeSelectOption, TreeSelectSlots } from './types';
|
|
42
|
+
import { treeSelectEmitsPrivate as emits, treeSelectPropsPrivate as props } from './types';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @file 分类选择器
|
|
46
|
+
*/
|
|
47
|
+
export default defineComponent({
|
|
48
|
+
name: 'HTreeSelect',
|
|
49
|
+
components: { VanTreeSelect, VanField, VanPopup },
|
|
50
|
+
inheritAttrs: false,
|
|
51
|
+
props,
|
|
52
|
+
emits,
|
|
53
|
+
slots: Object as SlotsType<TreeSelectSlots>,
|
|
54
|
+
setup(props, ctx) {
|
|
55
|
+
const plain = usePlain(props);
|
|
56
|
+
const { slotProps } = useCommonSetup(props, ctx, plain);
|
|
57
|
+
/** 展示在页面上的值 */
|
|
58
|
+
const showText = computed(() => {
|
|
59
|
+
const value = plain.checked.value as string | string[];
|
|
60
|
+
if (!value) return '';
|
|
61
|
+
const { format, separator } = props;
|
|
62
|
+
const source = (props.treeSelectProps?.items || plain.finalOption.value) as TreeSelectOption[];
|
|
63
|
+
if (format) return format({ source, value, separator });
|
|
64
|
+
const result: string[] = [];
|
|
65
|
+
let _item: TreeSelectOption['children'][number] | undefined;
|
|
66
|
+
if (typeof value === 'string') {
|
|
67
|
+
source.some((o) => {
|
|
68
|
+
_item = o.children.find((oo) => oo.id === value);
|
|
69
|
+
_item && result.push(_item.text);
|
|
70
|
+
return !!_item;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
value.forEach((val) => source.some((oo) => {
|
|
75
|
+
_item = oo.children.find((ooo) => ooo.id === val);
|
|
76
|
+
_item && result.push(_item.text);
|
|
77
|
+
return !!_item;
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
return result.filter(Boolean).join(separator);
|
|
81
|
+
});
|
|
82
|
+
/** 点击事件 */
|
|
83
|
+
function clickHandle(ev: MouseEvent) {
|
|
84
|
+
if (plain.globalDisabled.value || props.disabled || plain.globalReadonly.value || props.readonly) return;
|
|
85
|
+
props.onRowClick ? props.onRowClick(popupInfo.value, ev) : popupInfo.value.open();
|
|
86
|
+
}
|
|
87
|
+
/** 左侧激活项 */
|
|
88
|
+
const mainActiveIndex = ref(0);
|
|
89
|
+
let tempChecked: any;
|
|
90
|
+
watch(
|
|
91
|
+
[plain.checked, plain.finalOption],
|
|
92
|
+
([val, options]) => {
|
|
93
|
+
if (!options?.length) return;
|
|
94
|
+
// 两者相等, 说明是 activeIdChange, 可以直接返回
|
|
95
|
+
if (tempChecked === val) {
|
|
96
|
+
tempChecked = null;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
tempChecked = null;
|
|
100
|
+
// 直接重置为 0
|
|
101
|
+
mainActiveIndex.value = 0;
|
|
102
|
+
if (!(val && val.length)) return;
|
|
103
|
+
// 如果是字符串, 直接赋值所在下标
|
|
104
|
+
if (typeof val === 'string') {
|
|
105
|
+
let flag: boolean;
|
|
106
|
+
(options as TreeSelectOption[]).some((o, idx) => {
|
|
107
|
+
flag = o.children.some((oo) => oo.id === val);
|
|
108
|
+
flag && (mainActiveIndex.value = idx);
|
|
109
|
+
return flag;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// 如果是数组, 取最小的一个下标
|
|
114
|
+
const idxs = (val as string[]).map((o) => (options as TreeSelectOption[]).findIndex((oo) => oo.children.some((ooo) => ooo.id === o)));
|
|
115
|
+
// Math.max 兜底处理, 防止出现 -1
|
|
116
|
+
mainActiveIndex.value = Math.max(0, Math.min(...idxs));
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{ immediate: true },
|
|
120
|
+
);
|
|
121
|
+
/** 左侧标签更改事件 */
|
|
122
|
+
function mainActiveIndexChange(index: number) {
|
|
123
|
+
mainActiveIndex.value = index;
|
|
124
|
+
}
|
|
125
|
+
/** 右侧更改事件 */
|
|
126
|
+
function activeIdChange(value: string | string[]) {
|
|
127
|
+
plain.change(value);
|
|
128
|
+
tempChecked = plain.checked.value;
|
|
129
|
+
nextTick(() => tempChecked = null);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** 弹窗显示状态 */
|
|
133
|
+
const popupInfo = ref({
|
|
134
|
+
visible: false,
|
|
135
|
+
open() {
|
|
136
|
+
popupInfo.value.visible = true;
|
|
137
|
+
},
|
|
138
|
+
close() {
|
|
139
|
+
popupInfo.value.visible = false;
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
hyphenate,
|
|
145
|
+
getNode,
|
|
146
|
+
...plain,
|
|
147
|
+
slotProps,
|
|
148
|
+
showText,
|
|
149
|
+
clickHandle,
|
|
150
|
+
mainActiveIndex,
|
|
151
|
+
mainActiveIndexChange,
|
|
152
|
+
activeIdChange,
|
|
153
|
+
popupInfo,
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
</script>
|
|
158
|
+
|
|
159
|
+
<style lang="scss" scoped>
|
|
160
|
+
</style>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { emits2obj, PlainProps } from '@xiaohaih/json-form-core';
|
|
2
|
+
import { emits2props, plainProps } from '@xiaohaih/json-form-core';
|
|
3
|
+
import type { TreeSelectChild, Popup as VanPopup } from 'vant';
|
|
4
|
+
import { Field as VanField, TreeSelect as VanTreeSelect } from 'vant';
|
|
5
|
+
import type { ExtractPublicPropTypes, PropType } from 'vue';
|
|
6
|
+
import type { ComponentEmit, ComponentExposed, ComponentProps } from 'vue-component-type-helpers';
|
|
7
|
+
import type { PickerOption } from '../picker/types';
|
|
8
|
+
import type { CommonProps, CommonSlots, CommonSlotsProps, ComponentType } from '../share';
|
|
9
|
+
import { commonProps } from '../share';
|
|
10
|
+
|
|
11
|
+
/** 组件传参 - 私有 */
|
|
12
|
+
export function treeSelectPropsGeneric<Query extends Record<string, any>, OptionQuery extends Record<string, any>>() {
|
|
13
|
+
return {
|
|
14
|
+
...commonProps as CommonProps<Query, OptionQuery>,
|
|
15
|
+
...plainProps as PlainProps<Query, OptionQuery>,
|
|
16
|
+
/** VanTreeSelect 组件的属性 */
|
|
17
|
+
treeSelectProps: { type: Object as PropType<Partial<ComponentProps<typeof VanTreeSelect>>> },
|
|
18
|
+
/** VanTreeSelect 组件的事件 - 兼容 vue2 版本 */
|
|
19
|
+
treeSelectOn: { type: Object as PropType<Partial<ReturnType<typeof emits2obj<NonNullable<typeof VanTreeSelect.emits>>>>>, default: () => ({}) },
|
|
20
|
+
/** VanTreeSelect 组件的插槽 */
|
|
21
|
+
treeSelectSlots: { type: Object as PropType<{
|
|
22
|
+
/** 自定义导航名称 */
|
|
23
|
+
navText?: ComponentType<{ item: TreeSelectChild } & CommonSlotsProps<any, any>>;
|
|
24
|
+
/** 自定义右侧区域内容 */
|
|
25
|
+
content?: ComponentType<{ options: any[] } & CommonSlotsProps<any, any>>;
|
|
26
|
+
}> },
|
|
27
|
+
/** 是否展示右侧箭头并开启点击反馈 - Field 字段, 调整默认值 */
|
|
28
|
+
isLink: { type: Boolean, default: true },
|
|
29
|
+
/** 点击事件, 当传递了此事件时, 会忽略内部打开弹窗操作 */
|
|
30
|
+
onRowClick: { type: Function as PropType<(option: { open: () => void; close: () => void }, ev: MouseEvent) => void> },
|
|
31
|
+
/** 显示文本的分隔符 @default / */
|
|
32
|
+
separator: { type: String, default: ',' },
|
|
33
|
+
/** 对值进行格式化 - 显示在页面上的值 */
|
|
34
|
+
format: { type: Function as PropType<(option: {
|
|
35
|
+
source: TreeSelectOption[];
|
|
36
|
+
value: string | string[];
|
|
37
|
+
separator: string;
|
|
38
|
+
}) => any> },
|
|
39
|
+
/** 值触发方式 @default confirm */
|
|
40
|
+
valueTrigger: { type: String as PropType<'change' | 'confirm' | 'cancel'>, default: 'confirm' },
|
|
41
|
+
/** 弹窗组件的属性 */
|
|
42
|
+
popupProps: { type: Object as PropType<Partial<ComponentExposed<typeof VanPopup>>> },
|
|
43
|
+
/** 弹窗组件的事件 - 兼容 vue2 版本 */
|
|
44
|
+
popupOn: { type: Object as PropType<Partial<ReturnType<typeof emits2obj<NonNullable<typeof VanPopup.emits>>>>>, default: () => ({}) },
|
|
45
|
+
} as const;
|
|
46
|
+
}
|
|
47
|
+
/** 组件传参 - 私有 */
|
|
48
|
+
export const treeSelectPropsPrivate = treeSelectPropsGeneric();
|
|
49
|
+
/** 组件传参 - 外部调用 */
|
|
50
|
+
export const treeSelectProps = {
|
|
51
|
+
...VanField.props as unknown as {},
|
|
52
|
+
...treeSelectPropsPrivate,
|
|
53
|
+
};
|
|
54
|
+
export type TreeSelectProps<Query extends Record<string, any>, OptionQuery extends Record<string, any>> = ExtractPublicPropTypes<ReturnType<typeof treeSelectPropsGeneric<Query, OptionQuery>>>;
|
|
55
|
+
|
|
56
|
+
/** 组件事件 - 私有 */
|
|
57
|
+
export function treeSelectEmitsGeneric<T>() {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
/** 组件事件 - 私有 */
|
|
61
|
+
export const treeSelectEmitsPrivate = treeSelectEmitsGeneric();
|
|
62
|
+
/** 组件事件 - 外部调用 */
|
|
63
|
+
export const treeSelectEmits = {
|
|
64
|
+
...VanField.emits,
|
|
65
|
+
...treeSelectEmitsPrivate,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type TreeSelectEmits<T> = ReturnType<typeof treeSelectEmitsGeneric<T>>;
|
|
69
|
+
|
|
70
|
+
export interface TreeSelectSlots extends CommonSlots<any> {
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface TreeSelectOption {
|
|
74
|
+
text: string;
|
|
75
|
+
id: string;
|
|
76
|
+
children: Omit<TreeSelectOption, 'children'>[];
|
|
77
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<VanField
|
|
3
|
+
v-if="!hide"
|
|
4
|
+
:name="field"
|
|
5
|
+
:disabled="globalDisabled || disabled"
|
|
6
|
+
:readonly="globalReadonly || readonly"
|
|
7
|
+
v-bind="$attrs"
|
|
8
|
+
>
|
|
9
|
+
<template #input>
|
|
10
|
+
<VanUploader
|
|
11
|
+
:disabled="globalDisabled || disabled"
|
|
12
|
+
:readonly="globalReadonly || readonly"
|
|
13
|
+
:afterRead="rewriteAfterRead"
|
|
14
|
+
:model-value="checked"
|
|
15
|
+
v-bind="uploadProps" v-on="uploadOn"
|
|
16
|
+
@update:model-value="change"
|
|
17
|
+
>
|
|
18
|
+
<template v-for="(item, slotName) of uploadSlots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
19
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" />
|
|
20
|
+
</template>
|
|
21
|
+
</VanUploader>
|
|
22
|
+
</template>
|
|
23
|
+
<template v-for="(item, slotName) of slots" :key="slotName" #[hyphenate(slotName)]="row">
|
|
24
|
+
<component :is="getNode(item)" v-bind="slotProps" v-bind.prop="row" />
|
|
25
|
+
</template>
|
|
26
|
+
</VanField>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script lang="ts">
|
|
30
|
+
import { getNode, hyphenate, usePlain } from '@xiaohaih/json-form-core';
|
|
31
|
+
import { Field as VanField, Uploader as VanUploader } from 'vant';
|
|
32
|
+
import type { SlotsType } from 'vue';
|
|
33
|
+
import { defineComponent, unref } from 'vue';
|
|
34
|
+
import { useCommonSetup } from '../use';
|
|
35
|
+
import type { FileInfo, UploadDetail, UploadOption, UploadSlots } from './types';
|
|
36
|
+
import { uploadEmitsPrivate as emits, uploadPropsPrivate as props } from './types';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @file 上传
|
|
40
|
+
*/
|
|
41
|
+
export default defineComponent({
|
|
42
|
+
name: 'HUploader',
|
|
43
|
+
components: { VanField, VanUploader },
|
|
44
|
+
inheritAttrs: false,
|
|
45
|
+
props,
|
|
46
|
+
emits,
|
|
47
|
+
slots: Object as SlotsType<UploadSlots>,
|
|
48
|
+
setup(props, ctx) {
|
|
49
|
+
const plain = usePlain(props);
|
|
50
|
+
const { slotProps } = useCommonSetup(props, ctx, plain);
|
|
51
|
+
|
|
52
|
+
/** 重写文件上传功能 */
|
|
53
|
+
function rewriteAfterRead(file: FileInfo | FileInfo[], detail: UploadDetail) {
|
|
54
|
+
const opt = getUploadOption(file, detail);
|
|
55
|
+
if (props.afterRead) return props.afterRead(file, detail, opt);
|
|
56
|
+
if (!props.uploadRequest) return;
|
|
57
|
+
|
|
58
|
+
opt.files.forEach((o) => {
|
|
59
|
+
o.status = 'uploading';
|
|
60
|
+
o.message = typeof props.uploadingMessage === 'function' ? props.uploadingMessage(o) : props.uploadingMessage;
|
|
61
|
+
});
|
|
62
|
+
const res = props.uploadRequest(opt);
|
|
63
|
+
typeof res === 'object' && (res.then ? res.then(opt.success.bind(null, opt.files)) : res.catch(opt.fail.bind(null, opt.files)));
|
|
64
|
+
}
|
|
65
|
+
function getUploadOption(file: FileInfo | FileInfo[], detail: UploadDetail) {
|
|
66
|
+
return {
|
|
67
|
+
file: Array.isArray(file) ? file[0] : file,
|
|
68
|
+
files: Array.isArray(file) ? file : [file],
|
|
69
|
+
success: successCallback,
|
|
70
|
+
fail: failCallback,
|
|
71
|
+
} as UploadOption;
|
|
72
|
+
}
|
|
73
|
+
function successCallback(file: FileInfo | FileInfo[], res: any) {
|
|
74
|
+
const files = Array.isArray(file) ? file : [file];
|
|
75
|
+
files.some((o) => {
|
|
76
|
+
if (o.status !== 'uploading') return false;
|
|
77
|
+
o.status = 'done';
|
|
78
|
+
o.message = '';
|
|
79
|
+
o.response = res;
|
|
80
|
+
return false;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function failCallback(file: FileInfo | FileInfo[], res: any) {
|
|
84
|
+
const files = Array.isArray(file) ? file : [file];
|
|
85
|
+
files.some((o) => {
|
|
86
|
+
if (o.status !== 'uploading') return false;
|
|
87
|
+
o.status = 'failed';
|
|
88
|
+
o.message = typeof props.failedMessage === 'function' ? props.failedMessage(o, res) : props.failedMessage;
|
|
89
|
+
o.response = res;
|
|
90
|
+
return false;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
hyphenate,
|
|
96
|
+
getNode,
|
|
97
|
+
...plain,
|
|
98
|
+
slotProps,
|
|
99
|
+
rewriteAfterRead,
|
|
100
|
+
getUploadOption,
|
|
101
|
+
successCallback,
|
|
102
|
+
failCallback,
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<style lang="scss" scoped>
|
|
109
|
+
</style>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { emits2obj, PlainProps } from '@xiaohaih/json-form-core';
|
|
2
|
+
import { emits2props, plainProps } from '@xiaohaih/json-form-core';
|
|
3
|
+
import type { PopupProps, UploaderFileListItem } from 'vant';
|
|
4
|
+
import { Field as VanField, Uploader as VanUploader } from 'vant';
|
|
5
|
+
import type { ExtractPublicPropTypes, PropType } from 'vue';
|
|
6
|
+
import type { ComponentProps } from 'vue-component-type-helpers';
|
|
7
|
+
import type { CommonProps, CommonSlots, CommonSlotsProps, ComponentType } from '../share';
|
|
8
|
+
import { commonProps } from '../share';
|
|
9
|
+
|
|
10
|
+
/** 组件传参 - 私有 */
|
|
11
|
+
export function uploadPropsGeneric<Query extends Record<string, any>, OptionQuery extends Record<string, any>>() {
|
|
12
|
+
return {
|
|
13
|
+
...commonProps as CommonProps<Query, OptionQuery>,
|
|
14
|
+
...plainProps as PlainProps<Query, OptionQuery>,
|
|
15
|
+
/** VanUploader 组件的属性 */
|
|
16
|
+
uploadProps: { type: Object as PropType<Partial<ComponentProps<typeof VanUploader>>> },
|
|
17
|
+
/** VanUploader 组件的事件 - 兼容 vue2 版本 */
|
|
18
|
+
uploadOn: { type: Object as PropType<Partial<ReturnType<typeof emits2obj<NonNullable<typeof VanUploader.emits>>>>>, default: () => ({}) },
|
|
19
|
+
/** VanUploader 组件的插槽 */
|
|
20
|
+
uploadSlots: { type: Object as PropType<{
|
|
21
|
+
/** 自定义上传区域 */
|
|
22
|
+
default?: ComponentType<CommonSlotsProps<any, any>>;
|
|
23
|
+
/** 自定义删除按钮 */
|
|
24
|
+
previewDelete?: ComponentType<CommonSlotsProps<any, any>>;
|
|
25
|
+
/** 自定义覆盖在预览区域上方的内容 */
|
|
26
|
+
previewCover?: ComponentType<{ item: UploaderFileListItem } & CommonSlotsProps<any, any>>;
|
|
27
|
+
}> },
|
|
28
|
+
/** 文件读取完毕后执行的回调 */
|
|
29
|
+
afterRead: { type: Function as PropType<(file: FileInfo | FileInfo[], detail: UploadDetail, option: UploadOption) => void> },
|
|
30
|
+
/** 文件上传方法 */
|
|
31
|
+
uploadRequest: { type: Function as PropType<(option: UploadOption) => Promise<any> | void> },
|
|
32
|
+
/** 上传中的提示 */
|
|
33
|
+
uploadingMessage: { type: [String, Function] as PropType<string | ((fileInfo: FileInfo) => string)>, default: '上传中' },
|
|
34
|
+
/** 失败的提示 */
|
|
35
|
+
failedMessage: { type: [String, Function] as PropType<string | ((fileInfo: FileInfo, response: any) => string)> },
|
|
36
|
+
} as const;
|
|
37
|
+
}
|
|
38
|
+
/** 组件传参 - 私有 */
|
|
39
|
+
export const uploadPropsPrivate = uploadPropsGeneric();
|
|
40
|
+
/** 组件传参 - 外部调用 */
|
|
41
|
+
export const uploadProps = {
|
|
42
|
+
...VanField.props as unknown as {},
|
|
43
|
+
...uploadPropsPrivate,
|
|
44
|
+
};
|
|
45
|
+
export type UploadProps<Query extends Record<string, any>, OptionQuery extends Record<string, any>> = ExtractPublicPropTypes<ReturnType<typeof uploadPropsGeneric<Query, OptionQuery>>>;
|
|
46
|
+
|
|
47
|
+
/** 组件事件 - 私有 */
|
|
48
|
+
export function uploadEmitsGeneric<T>() {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
/** 组件事件 - 私有 */
|
|
52
|
+
export const uploadEmitsPrivate = uploadEmitsGeneric();
|
|
53
|
+
/** 组件事件 - 外部调用 */
|
|
54
|
+
export const uploadEmits = {
|
|
55
|
+
...VanField.emits,
|
|
56
|
+
...uploadEmitsPrivate,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type UploadEmits<T> = ReturnType<typeof uploadEmitsGeneric<T>>;
|
|
60
|
+
|
|
61
|
+
export interface UploadSlots extends CommonSlots<any> {
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** 上传文件信息 */
|
|
65
|
+
export interface FileInfo extends UploaderFileListItem {
|
|
66
|
+
/** 服务器返回的信息 */
|
|
67
|
+
response?: any;
|
|
68
|
+
}
|
|
69
|
+
/** */
|
|
70
|
+
export interface UploadDetail {
|
|
71
|
+
name: number | string;
|
|
72
|
+
index: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** 文件上传提供的参数 */
|
|
76
|
+
export interface UploadOption {
|
|
77
|
+
/** 当前选中的第一个文件 */
|
|
78
|
+
file: FileInfo;
|
|
79
|
+
/** 多选时所有文件 */
|
|
80
|
+
files: FileInfo[];
|
|
81
|
+
/** 成功回调 */
|
|
82
|
+
success: (file: FileInfo | FileInfo[], res: any) => void;
|
|
83
|
+
/** 失败回调 */
|
|
84
|
+
fail: (file: FileInfo | FileInfo[], res: any) => void;
|
|
85
|
+
}
|