forked from youzan/vant
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomponent.ts
More file actions
77 lines (65 loc) · 2.08 KB
/
component.ts
File metadata and controls
77 lines (65 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
* Create a basic component with common options
*/
import '../../locale';
import { camelize } from '../format/string';
import { SlotsMixin } from '../../mixins/slots';
import Vue, { VNode, VueConstructor, ComponentOptions, RenderContext } from 'vue';
import { DefaultProps, FunctionComponent } from '../types';
export interface VantComponentOptions extends ComponentOptions<Vue> {
functional?: boolean;
install?: (Vue: VueConstructor) => void;
}
export type TsxBaseProps<Slots> = {
key: string | number;
// hack for jsx prop spread
props: any;
class: any;
style: string | object[] | object;
scopedSlots: Slots;
};
export type TsxComponent<Props, Events, Slots> = (
props: Partial<Props & Events & TsxBaseProps<Slots>>
) => VNode;
function install(this: ComponentOptions<Vue>, Vue: VueConstructor) {
const { name } = this;
Vue.component(name as string, this);
Vue.component(camelize(`-${name}`), this);
}
// unify slots & scopedSlots
export function unifySlots(context: RenderContext) {
// use data.scopedSlots in lower Vue version
const scopedSlots = context.scopedSlots || context.data.scopedSlots || {};
const slots = context.slots();
Object.keys(slots).forEach(key => {
if (!scopedSlots[key]) {
scopedSlots[key] = () => slots[key];
}
});
return scopedSlots;
}
// should be removed after Vue 3
function transformFunctionComponent(pure: FunctionComponent): VantComponentOptions {
return {
functional: true,
props: pure.props,
model: pure.model,
render: (h, context): any => pure(h, context.props, unifySlots(context), context)
};
}
export function createComponent(name: string) {
return function<Props = DefaultProps, Events = {}, Slots = {}> (
sfc: VantComponentOptions | FunctionComponent
): TsxComponent<Props, Events, Slots> {
if (typeof sfc === 'function') {
sfc = transformFunctionComponent(sfc);
}
if (!sfc.functional) {
sfc.mixins = sfc.mixins || [];
sfc.mixins.push(SlotsMixin);
}
sfc.name = name;
sfc.install = install;
return sfc as TsxComponent<Props, Events, Slots>;
};
}