Skip to content

Commit 205e164

Browse files
authored
feat(element): support element-ui slot (#2162)
1 parent cdf8405 commit 205e164

File tree

13 files changed

+139
-89
lines changed

13 files changed

+139
-89
lines changed

packages/element/src/__builtins__/shared/get-component-by-tag.ts

Lines changed: 0 additions & 55 deletions
This file was deleted.

packages/element/src/__builtins__/shared/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './get-component-by-tag'
1+
export * from './transform-component'
22
export * from './resolve-component'
33
export * from './create-context'
44
export * from './utils'

packages/element/src/__builtins__/shared/resolve-component.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1+
import { Component } from 'vue'
12
import { h, toRaw } from '@vue/composition-api'
2-
import { Component, VNode } from 'vue'
3+
import { SlotTypes } from '.'
4+
import { isVnode } from './utils'
35

46
export const resolveComponent = (
5-
child?:
6-
| Component
7-
| string
8-
| number
9-
| boolean
10-
| ((...args: any[]) => VNode[] | VNode),
7+
child?: SlotTypes,
118
props?: Record<string, any>
129
) => {
1310
if (child) {
14-
if (
15-
typeof child === 'string' ||
16-
typeof child === 'number' ||
17-
typeof child === 'boolean'
18-
) {
11+
if (typeof child === 'string' || typeof child === 'number') {
1912
return child
2013
} else if (typeof child === 'function') {
2114
return (child as Function)(props)
15+
} else if (isVnode(child)) {
16+
return child
2217
} else {
23-
return h(toRaw(child), { props })
18+
return h(toRaw(child as Component), { props })
2419
}
2520
}
2621

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import type { Component } from 'vue'
2+
import { merge } from '@formily/shared'
3+
import { h } from '@formily/vue'
4+
import { isVue2, h as hInVue2, defineComponent } from 'vue-demi'
5+
6+
type ListenersTransformRules = Record<string, string>
7+
8+
export const transformComponent = <T extends Record<string, any>>(
9+
tag: any,
10+
transformRules?: ListenersTransformRules,
11+
defaultProps?: Partial<T>
12+
): Component<T> | any => {
13+
if (isVue2) {
14+
return defineComponent({
15+
setup(props, { attrs, slots, listeners }) {
16+
return () => {
17+
const data = {
18+
attrs: {
19+
...attrs,
20+
},
21+
on: {
22+
...listeners,
23+
},
24+
}
25+
26+
if (transformRules) {
27+
const transformListeners = transformRules
28+
Object.keys(transformListeners).forEach((extract) => {
29+
if (data.on !== undefined) {
30+
data.on[transformListeners[extract]] = listeners[extract]
31+
}
32+
})
33+
}
34+
if (defaultProps) {
35+
data.attrs = merge(defaultProps, data.attrs)
36+
}
37+
38+
return h(tag, data, slots)
39+
}
40+
},
41+
})
42+
} else {
43+
return defineComponent({
44+
setup(props, { attrs, slots }) {
45+
return () => {
46+
let data = {
47+
...attrs,
48+
}
49+
if (transformRules) {
50+
const listeners = transformRules
51+
Object.keys(listeners).forEach((extract) => {
52+
const event = listeners[extract]
53+
data[`on${event[0].toUpperCase()}${event.slice(1)}`] =
54+
attrs[`on${extract[0].toUpperCase()}${extract.slice(1)}`]
55+
})
56+
}
57+
if (defaultProps) {
58+
data = merge(defaultProps, data)
59+
}
60+
return h(tag, data, slots)
61+
}
62+
},
63+
})
64+
}
65+
}

packages/element/src/__builtins__/shared/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ export function isValidElement(element) {
99
) // remove text node
1010
}
1111

12+
export function isVnode(element: any): boolean {
13+
return (
14+
element &&
15+
typeof element === 'object' &&
16+
'componentOptions' in element &&
17+
'context' in element &&
18+
element.tag !== undefined
19+
)
20+
}
21+
1222
export function isVueOptions(options) {
1323
return (
1424
options &&

packages/element/src/checkbox/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { connect, mapProps, h, mapReadPretty } from '@formily/vue'
22
import { defineComponent, PropType } from '@vue/composition-api'
33
import {
44
composeExport,
5-
getComponentByTag,
5+
transformComponent,
66
resolveComponent,
77
SlotTypes,
88
} from '../__builtins__/shared'
@@ -83,7 +83,7 @@ export type CheckboxGroupProps = ElCheckboxGroupProps & {
8383
optionType: 'default' | 'button'
8484
}
8585

86-
const TransformElCheckboxGroup = getComponentByTag(ElCheckboxGroup, {
86+
const TransformElCheckboxGroup = transformComponent(ElCheckboxGroup, {
8787
change: 'input',
8888
})
8989

packages/element/src/date-picker/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getComponentByTag } from '../__builtins__/shared'
1+
import { transformComponent } from '../__builtins__/shared'
22
import { connect, mapProps, mapReadPretty } from '@formily/vue'
33

44
import type { DatePicker as ElDatePickerProps } from 'element-ui'
@@ -7,9 +7,12 @@ import { PreviewText } from '../preview-text'
77

88
export type DatePickerProps = ElDatePickerProps
99

10-
const TransformElDatePicker = getComponentByTag<DatePickerProps>(ElDatePicker, {
11-
change: 'input',
12-
})
10+
const TransformElDatePicker = transformComponent<DatePickerProps>(
11+
ElDatePicker,
12+
{
13+
change: 'input',
14+
}
15+
)
1316

1417
const getDefaultFormat = (props, formatType = 'format') => {
1518
const type = props.type

packages/element/src/input-number/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getComponentByTag } from '../__builtins__/shared'
1+
import { transformComponent } from '../__builtins__/shared'
22
import { connect, mapProps, mapReadPretty } from '@formily/vue'
33

44
import type { InputNumber as _ElInputNumberProps } from 'element-ui'
@@ -7,7 +7,7 @@ import { PreviewText } from '../preview-text'
77

88
export type InputNumberProps = _ElInputNumberProps
99

10-
const TransformElInputNumber = getComponentByTag<InputNumberProps>(
10+
const TransformElInputNumber = transformComponent<InputNumberProps>(
1111
ElInputNumber,
1212
{
1313
change: 'input',

packages/element/src/input/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { composeExport, getComponentByTag } from '../__builtins__/shared'
1+
import { composeExport, transformComponent } from '../__builtins__/shared'
22
import { connect, mapProps, mapReadPretty } from '@formily/vue'
33
import { PreviewText } from '../preview-text'
44
import type { Input as ElInputProps } from 'element-ui'
55
import { Input as ElInput } from 'element-ui'
66

77
export type InputProps = ElInputProps
88

9-
const TransformElInput = getComponentByTag<InputProps>(ElInput, {
9+
const TransformElInput = transformComponent<InputProps>(ElInput, {
1010
change: 'input',
1111
})
1212

packages/element/src/radio/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { connect, mapProps, h, mapReadPretty } from '@formily/vue'
22
import { defineComponent, PropType } from '@vue/composition-api'
33
import {
44
composeExport,
5-
getComponentByTag,
5+
transformComponent,
66
resolveComponent,
77
SlotTypes,
88
} from '../__builtins__/shared'
@@ -31,7 +31,7 @@ export type RadioGroupProps = ElRadioGroupProps & {
3131

3232
export type RadioProps = ElRadioProps
3333

34-
const TransformElRadioGroup = getComponentByTag(ElRadioGroup, {
34+
const TransformElRadioGroup = transformComponent(ElRadioGroup, {
3535
change: 'input',
3636
})
3737

0 commit comments

Comments
 (0)