Skip to content

Commit b4ff08e

Browse files
author
Andy
committed
Merge branch 'feat-vue3' of https://github.com/vueComponent/ant-design-vue into feat-vue3
2 parents 3840666 + 7eeee69 commit b4ff08e

File tree

16 files changed

+346
-354
lines changed

16 files changed

+346
-354
lines changed

components/_util/props-util.js

+64-21
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,39 @@ const getSlots = ele => {
6767
});
6868
return { ...slots, ...getScopedSlots(ele) };
6969
};
70+
71+
const flattenChildren = (children = [], filterEmpty = true) => {
72+
const temp = Array.isArray(children) ? children : [children];
73+
const res = [];
74+
temp.forEach(child => {
75+
if (Array.isArray(child)) {
76+
res.push(...flattenChildren(child, filterEmpty));
77+
} else if (child && child.type === Fragment) {
78+
res.push(...flattenChildren(child.children, filterEmpty));
79+
} else if (child && isVNode(child)) {
80+
if (filterEmpty && !isEmptyElement(child)) {
81+
res.push(child);
82+
} else if (!filterEmpty) {
83+
res.push(child);
84+
}
85+
}
86+
});
87+
return res;
88+
};
89+
7090
const getSlot = (self, name = 'default', options = {}) => {
71-
let res = self.$slots[name] && self.$slots[name](options);
72-
while (res && res.length === 1 && (res[0].type === Fragment || Array.isArray(res[0]))) {
73-
res = res[0].children || res[0];
91+
if (isVNode(self)) {
92+
if (self.type === Fragment) {
93+
return name === 'default' ? flattenChildren(self.children) : [];
94+
} else if (self.children && self.children[name]) {
95+
return flattenChildren(self.children[name](options));
96+
} else {
97+
return [];
98+
}
99+
} else {
100+
let res = self.$slots[name] && self.$slots[name](options);
101+
return flattenChildren(res);
74102
}
75-
return res && res.__v_isVNode ? [res] : res;
76103
};
77104

78105
const getAllChildren = ele => {
@@ -95,7 +122,7 @@ const getSlotOptions = ele => {
95122
};
96123
const findDOMNode = instance => {
97124
let node = instance.$el;
98-
while (!node.tagName) {
125+
while (node && !node.tagName) {
99126
node = node.nextSibling;
100127
}
101128
return node;
@@ -127,27 +154,33 @@ const getOptionProps = instance => {
127154
}
128155
return res;
129156
};
130-
const getComponent = (instance, prop, options = instance, execute = true) => {
157+
const getComponent = (instance, prop = 'default', options = instance, execute = true) => {
158+
let com = undefined;
131159
if (instance.$) {
132160
const temp = instance[prop];
133161
if (temp !== undefined) {
134162
return typeof temp === 'function' && execute ? temp(options) : temp;
135163
} else {
136-
let com = instance.$slots[prop];
164+
com = instance.$slots[prop];
137165
com = execute && com ? com(options) : com;
138-
return Array.isArray(com) && com.length === 1 ? com[0] : com;
139166
}
140167
} else if (isVNode(instance)) {
141168
const temp = instance.props && instance.props[prop];
142-
if (temp !== undefined) {
169+
if (temp !== undefined && instance.props !== null) {
143170
return typeof temp === 'function' && execute ? temp(options) : temp;
171+
} else if (instance.type === Fragment) {
172+
com = instance.children;
144173
} else if (instance.children && instance.children[prop]) {
145-
let com = instance.children[prop];
174+
com = instance.children[prop];
146175
com = execute && com ? com(options) : com;
147-
return Array.isArray(com) && com.length === 1 ? com[0] : com;
148176
}
149177
}
150-
return undefined;
178+
if (Array.isArray(com)) {
179+
com = flattenChildren(com);
180+
com = com.length === 1 ? com[0] : com;
181+
com = com.length === 0 ? undefined : com;
182+
}
183+
return com;
151184
};
152185
const getComponentFromProp = (instance, prop, options = instance, execute = true) => {
153186
if (instance.$createElement) {
@@ -200,7 +233,8 @@ const getAllProps = ele => {
200233
return props;
201234
};
202235

203-
const getPropsData = vnode => {
236+
const getPropsData = ins => {
237+
const vnode = ins.$ ? ins.$ : ins;
204238
const res = {};
205239
const originProps = vnode.props || {};
206240
const props = {};
@@ -231,9 +265,6 @@ const getAttrs = ele => {
231265

232266
const getKey = ele => {
233267
let key = ele.key;
234-
if (ele.$vnode) {
235-
key = ele.$vnode.key;
236-
}
237268
return key;
238269
};
239270

@@ -307,18 +338,29 @@ export function isFragment(c) {
307338
}
308339

309340
export function isEmptyElement(c) {
310-
return c.type === Comment || (c.type === Text && c.children.trim() === '');
341+
return (
342+
c.type === Comment ||
343+
(c.type === Fragment && c.children.length === 0) ||
344+
(c.type === Text && c.children.trim() === '')
345+
);
311346
}
312347

313348
export function isStringElement(c) {
314349
return !c.tag;
315350
}
316351

317352
export function filterEmpty(children = []) {
318-
if (isFragment(children)) {
319-
return children[0].children.filter(c => !isEmptyElement(c));
320-
}
321-
return children.filter(c => !isEmptyElement(c));
353+
const res = [];
354+
children.forEach(child => {
355+
if (Array.isArray(child)) {
356+
res.push(...child);
357+
} else if (child.type === Fragment) {
358+
res.push(...child.children);
359+
} else {
360+
res.push(child);
361+
}
362+
});
363+
return res.filter(c => !isEmptyElement(c));
322364
}
323365
const initDefaultProps = (propTypes, defaultProps) => {
324366
Object.keys(defaultProps).forEach(k => {
@@ -372,5 +414,6 @@ export {
372414
getAllProps,
373415
getAllChildren,
374416
findDOMNode,
417+
flattenChildren,
375418
};
376419
export default hasProp;

components/config-provider/index.jsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { reactive, provide } from 'vue';
22
import PropTypes from '../_util/vue-types';
3-
import { getComponentFromProp } from '../_util/props-util';
3+
import { getComponent } from '../_util/props-util';
44
import defaultRenderEmpty from './renderEmpty';
55
import LocaleProvider, { ANT_MARK } from '../locale-provider';
66
import LocaleReceiver from '../locale-provider/LocaleReceiver';
@@ -51,10 +51,9 @@ const ConfigProvider = {
5151
]),
5252
},
5353
methods: {
54-
renderEmptyComponent(h, name) {
55-
const renderEmpty =
56-
getComponentFromProp(this, 'renderEmpty', {}, false) || defaultRenderEmpty;
57-
return renderEmpty(h, name);
54+
renderEmptyComponent(name) {
55+
const renderEmpty = getComponent(this, 'renderEmpty', {}, false) || defaultRenderEmpty;
56+
return renderEmpty(name);
5857
},
5958
getPrefixCls(suffixCls, customizePrefixCls) {
6059
const { prefixCls = 'ant' } = this.$props;

components/grid/__tests__/__snapshots__/index.test.js.snap

+16-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@
33
exports[`Grid renders wrapped Col correctly 1`] = `
44
<div class="ant-row" style="margin-left: -10px; margin-right: -10px;">
55
<div>
6-
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"></div>
6+
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;">
7+
<!---->
8+
</div>
9+
</div>
10+
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;">
11+
<!---->
712
</div>
8-
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"></div>
913
</div>
1014
`;
1115

12-
exports[`Grid should render Col 1`] = `<div class="ant-col ant-col-2"></div>`;
16+
exports[`Grid should render Col 1`] = `
17+
<div class="ant-col ant-col-2">
18+
<!---->
19+
</div>
20+
`;
1321

14-
exports[`Grid should render Row 1`] = `<div class="ant-row"></div>`;
22+
exports[`Grid should render Row 1`] = `
23+
<div class="ant-row">
24+
<!---->
25+
</div>
26+
`;

components/grid/__tests__/index.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('Grid', () => {
77
mountTest(Col);
88
it('should render Col', () => {
99
const wrapper = mount(Col, {
10-
propsData: {
10+
props: {
1111
span: 2,
1212
},
1313
});

components/select/index.jsx

+44-53
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1+
import { provide, inject } from 'vue';
12
import warning from '../_util/warning';
23
import omit from 'omit.js';
34
import PropTypes from '../_util/vue-types';
45
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
56
import { ConfigConsumerProps } from '../config-provider';
67
import {
7-
getComponentFromProp,
8+
getComponent,
89
getOptionProps,
910
filterEmpty,
1011
isValidElement,
11-
getListeners,
12+
getSlot,
1213
} from '../_util/props-util';
1314
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
1415
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
1516
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
1617
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
1718
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
1819
import { cloneElement } from '../_util/vnode';
19-
import Base from '../base';
2020

2121
const AbstractSelectProps = () => ({
2222
prefixCls: PropTypes.string,
@@ -107,19 +107,13 @@ const Select = {
107107
choiceTransitionName: PropTypes.string.def('zoom'),
108108
},
109109
propTypes: SelectPropTypes,
110-
model: {
111-
prop: 'value',
112-
event: 'change',
113-
},
114-
provide() {
110+
setup() {
115111
return {
116-
savePopupRef: this.savePopupRef,
112+
configProvider: inject('configProvider', ConfigConsumerProps),
117113
};
118114
},
119-
inject: {
120-
configProvider: { default: () => ConfigConsumerProps },
121-
},
122115
created() {
116+
provide('savePopupRef', this.savePopupRef);
123117
warning(
124118
this.$props.mode !== 'combobox',
125119
'Select',
@@ -130,15 +124,14 @@ const Select = {
130124
},
131125
methods: {
132126
getNotFoundContent(renderEmpty) {
133-
const h = this.$createElement;
134-
const notFoundContent = getComponentFromProp(this, 'notFoundContent');
127+
const notFoundContent = getComponent(this, 'notFoundContent');
135128
if (notFoundContent !== undefined) {
136129
return notFoundContent;
137130
}
138131
if (this.isCombobox()) {
139132
return null;
140133
}
141-
return renderEmpty(h, 'Select');
134+
return renderEmpty('Select');
142135
},
143136
savePopupRef(ref) {
144137
this.popupRef = ref;
@@ -157,7 +150,7 @@ const Select = {
157150

158151
renderSuffixIcon(prefixCls) {
159152
const { loading } = this.$props;
160-
let suffixIcon = getComponentFromProp(this, 'suffixIcon');
153+
let suffixIcon = getComponent(this, 'suffixIcon');
161154
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
162155
if (suffixIcon) {
163156
return isValidElement(suffixIcon)
@@ -180,17 +173,18 @@ const Select = {
180173
showArrow,
181174
...restProps
182175
} = getOptionProps(this);
176+
const { class: className } = this.$attrs;
183177

184178
const getPrefixCls = this.configProvider.getPrefixCls;
185179
const renderEmpty = this.configProvider.renderEmpty;
186180
const prefixCls = getPrefixCls('select', customizePrefixCls);
187181

188182
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
189-
let removeIcon = getComponentFromProp(this, 'removeIcon');
183+
let removeIcon = getComponent(this, 'removeIcon');
190184
removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon;
191-
let clearIcon = getComponentFromProp(this, 'clearIcon');
185+
let clearIcon = getComponent(this, 'clearIcon');
192186
clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon;
193-
let menuItemSelectedIcon = getComponentFromProp(this, 'menuItemSelectedIcon');
187+
let menuItemSelectedIcon = getComponent(this, 'menuItemSelectedIcon');
194188
menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon)
195189
? menuItemSelectedIcon[0]
196190
: menuItemSelectedIcon;
@@ -203,6 +197,7 @@ const Select = {
203197
]);
204198

205199
const cls = {
200+
[className]: className,
206201
[`${prefixCls}-lg`]: size === 'large',
207202
[`${prefixCls}-sm`]: size === 'small',
208203
[`${prefixCls}-show-arrow`]: showArrow,
@@ -235,34 +230,32 @@ const Select = {
235230
: menuItemSelectedIcon)) || <CheckOutlined class={`${prefixCls}-selected-icon`} />;
236231

237232
const selectProps = {
238-
props: {
239-
inputIcon: this.renderSuffixIcon(prefixCls),
240-
removeIcon: finalRemoveIcon,
241-
clearIcon: finalClearIcon,
242-
menuItemSelectedIcon: finalMenuItemSelectedIcon,
243-
showArrow,
244-
...rest,
245-
...modeConfig,
246-
prefixCls,
247-
optionLabelProp: optionLabelProp || 'children',
248-
notFoundContent: this.getNotFoundContent(renderEmpty),
249-
maxTagPlaceholder: getComponentFromProp(this, 'maxTagPlaceholder'),
250-
placeholder: getComponentFromProp(this, 'placeholder'),
251-
children: options
252-
? options.map(option => {
253-
const { key, label = option.title, on, class: cls, style, ...restOption } = option;
254-
return (
255-
<Option key={key} {...{ props: restOption, on, class: cls, style }}>
256-
{label}
257-
</Option>
258-
);
259-
})
260-
: filterEmpty(this.$slots.default),
261-
__propsSymbol__: Symbol(),
262-
dropdownRender: getComponentFromProp(this, 'dropdownRender', {}, false),
263-
getPopupContainer: getPopupContainer || getContextPopupContainer,
264-
},
265-
on: getListeners(this),
233+
inputIcon: this.renderSuffixIcon(prefixCls),
234+
removeIcon: finalRemoveIcon,
235+
clearIcon: finalClearIcon,
236+
menuItemSelectedIcon: finalMenuItemSelectedIcon,
237+
showArrow,
238+
...rest,
239+
...modeConfig,
240+
prefixCls,
241+
optionLabelProp: optionLabelProp || 'children',
242+
notFoundContent: this.getNotFoundContent(renderEmpty),
243+
maxTagPlaceholder: getComponent(this, 'maxTagPlaceholder'),
244+
placeholder: getComponent(this, 'placeholder'),
245+
children: options
246+
? options.map(option => {
247+
const { key, label = option.title, on, class: cls, style, ...restOption } = option;
248+
return (
249+
<Option key={key} {...{ on, class: cls, style, ...restOption }}>
250+
{label}
251+
</Option>
252+
);
253+
})
254+
: filterEmpty(getSlot(this)),
255+
__propsSymbol__: Symbol(),
256+
dropdownRender: getComponent(this, 'dropdownRender', {}, false),
257+
getPopupContainer: getPopupContainer || getContextPopupContainer,
258+
...this.$attrs,
266259
class: cls,
267260
ref: 'vcSelect',
268261
};
@@ -271,11 +264,9 @@ const Select = {
271264
};
272265

273266
/* istanbul ignore next */
274-
Select.install = function(Vue) {
275-
Vue.use(Base);
276-
Vue.component(Select.name, Select);
277-
Vue.component(Select.Option.name, Select.Option);
278-
Vue.component(Select.OptGroup.name, Select.OptGroup);
267+
Select.install = function(app) {
268+
app.component(Select.name, Select);
269+
app.component(Select.Option.name, Select.Option);
270+
app.component(Select.OptGroup.name, Select.OptGroup);
279271
};
280-
281272
export default Select;

0 commit comments

Comments
 (0)