Skip to content

Commit ad6f343

Browse files
committed
feat: update autocomplete
1 parent 5e80e80 commit ad6f343

File tree

5 files changed

+104
-94
lines changed

5 files changed

+104
-94
lines changed

components/_util/props-util.js

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import isPlainObject from 'lodash/isPlainObject';
22
import classNames from 'classnames';
33
import { isVNode, Fragment, Comment, Text } from 'vue';
44
import { camelize, hyphenate, isOn, resolvePropValue } from './util';
5+
import isValid from './isValid';
56
// function getType(fn) {
67
// const match = fn && fn.toString().match(/^\s*function (\w+)/);
78
// return match ? match[1] : '';
@@ -82,6 +83,8 @@ const flattenChildren = (children = [], filterEmpty = true) => {
8283
} else if (!filterEmpty) {
8384
res.push(child);
8485
}
86+
} else if (isValid(child)) {
87+
res.push(child);
8588
}
8689
});
8790
return res;
+56-50
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,59 @@
1-
import PropTypes from '../_util/vue-types';
21
import { cloneElement } from '../_util/vnode';
3-
import { getOptionProps, getListeners } from '../_util/props-util';
4-
function chaining(...fns) {
5-
return function(...args) {
6-
// eslint-disable-line
7-
// eslint-disable-line
8-
for (let i = 0; i < fns.length; i++) {
9-
if (fns[i] && typeof fns[i] === 'function') {
10-
fns[i].apply(this, args);
11-
}
12-
}
13-
};
14-
}
15-
export default {
16-
name: 'InputElement',
17-
inheritAttrs: false,
18-
props: {
19-
value: PropTypes.any,
20-
disabled: PropTypes.bool,
21-
placeholder: PropTypes.string,
22-
},
23-
render() {
24-
const { $slots = {}, $attrs = {}, placeholder } = this;
25-
const listeners = getListeners(this);
26-
const props = getOptionProps(this);
27-
const value = props.value === undefined ? '' : props.value;
28-
const children = $slots.default[0];
29-
const { componentOptions = {} } = $slots.default[0];
30-
const { listeners: events = {} } = componentOptions;
31-
const newEvent = { ...events };
2+
import { flattenChildren } from '../_util/props-util';
3+
// function chaining(...fns) {
4+
// return function(...args) {
5+
// // eslint-disable-line
6+
// // eslint-disable-line
7+
// for (let i = 0; i < fns.length; i++) {
8+
// if (fns[i] && typeof fns[i] === 'function') {
9+
// fns[i].apply(this, args);
10+
// }
11+
// }
12+
// };
13+
// }
14+
// export default {
15+
// name: 'InputElement',
16+
// inheritAttrs: false,
17+
// props: {
18+
// value: PropTypes.any,
19+
// disabled: PropTypes.bool,
20+
// placeholder: PropTypes.string,
21+
// },
22+
// render() {
23+
// const { $slots = {}, $attrs = {}, placeholder } = this;
24+
// const listeners = getListeners(this);
25+
// const props = getOptionProps(this);
26+
// const value = props.value === undefined ? '' : props.value;
27+
// const children = getSlot(this)[0];
28+
// const { componentOptions = {} } = $slots.default[0];
29+
// const { listeners: events = {} } = componentOptions;
30+
// const newEvent = { ...events };
3231

33-
for (const [eventName, event] of Object.entries(listeners)) {
34-
newEvent[eventName] = chaining(event, events[eventName]);
35-
}
36-
const attrs = { ...$attrs, value };
37-
// https://github.com/vueComponent/ant-design-vue/issues/1761
38-
delete props.placeholder;
39-
if (placeholder) {
40-
props.placeholder = placeholder;
41-
attrs.placeholder = placeholder;
42-
}
43-
return cloneElement(children, {
44-
domProps: {
45-
value,
46-
},
47-
props,
48-
on: newEvent,
49-
attrs,
50-
ref: 'ele',
51-
});
52-
},
32+
// for (const [eventName, event] of Object.entries(listeners)) {
33+
// newEvent[eventName] = chaining(event, events[eventName]);
34+
// }
35+
// const attrs = { ...$attrs, value };
36+
// // https://github.com/vueComponent/ant-design-vue/issues/1761
37+
// delete props.placeholder;
38+
// if (placeholder) {
39+
// props.placeholder = placeholder;
40+
// attrs.placeholder = placeholder;
41+
// }
42+
// return cloneElement(children, {
43+
// domProps: {
44+
// value,
45+
// },
46+
// props,
47+
// on: newEvent,
48+
// attrs,
49+
// ref: 'ele',
50+
// });
51+
// },
52+
// };
53+
54+
const InputElement = (_, { attrs, slots }) => {
55+
const children = flattenChildren(slots.default?.())[0];
56+
return cloneElement(children, { ...attrs });
5357
};
58+
InputElement.inheritAttrs = false;
59+
export default InputElement;

components/auto-complete/index.jsx

+41-43
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1+
import { inject, provide } from 'vue';
12
import { Option, OptGroup } from '../vc-select';
23
import Select, { AbstractSelectProps, SelectValue } from '../select';
34
import Input from '../input';
45
import InputElement from './InputElement';
56
import PropTypes from '../_util/vue-types';
67
import { ConfigConsumerProps } from '../config-provider';
7-
import {
8-
getComponentFromProp,
9-
getOptionProps,
10-
filterEmpty,
11-
isValidElement,
12-
getListeners,
13-
} from '../_util/props-util';
14-
import Base from '../base';
8+
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
159

1610
// const DataSourceItemObject = PropTypes.shape({
1711
// value: String,
@@ -26,6 +20,9 @@ import Base from '../base';
2620
// onChange?: React.FormEventHandler<any>;
2721
// value: any;
2822
// }
23+
function isSelectOptionOrSelectOptGroup(child) {
24+
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
25+
}
2926

3027
const AutoCompleteProps = {
3128
...AbstractSelectProps(),
@@ -41,6 +38,7 @@ const AutoCompleteProps = {
4138

4239
const AutoComplete = {
4340
name: 'AAutoComplete',
41+
inheritAttrs: false,
4442
props: {
4543
...AutoCompleteProps,
4644
prefixCls: PropTypes.string.def('ant-select'),
@@ -55,59 +53,62 @@ const AutoComplete = {
5553
},
5654
Option: { ...Option, name: 'AAutoCompleteOption' },
5755
OptGroup: { ...OptGroup, name: 'AAutoCompleteOptGroup' },
58-
model: {
59-
prop: 'value',
60-
event: 'change',
61-
},
62-
inject: {
63-
configProvider: { default: () => ConfigConsumerProps },
64-
},
65-
provide() {
56+
// model: {
57+
// prop: 'value',
58+
// event: 'change',
59+
// },
60+
setup() {
6661
return {
67-
savePopupRef: this.savePopupRef,
62+
configProvider: inject('configProvider', ConfigConsumerProps),
6863
};
6964
},
65+
created() {
66+
provide('savePopupRef', this.savePopupRef);
67+
},
7068
methods: {
7169
savePopupRef(ref) {
7270
this.popupRef = ref;
7371
},
74-
72+
saveSelect(node) {
73+
this.select = node;
74+
},
7575
getInputElement() {
76-
const { $slots, placeholder } = this;
77-
const children = filterEmpty($slots.default);
76+
const { placeholder } = this;
77+
const children = getSlot(this);
7878
const element = children.length ? children[0] : <Input lazy={false} />;
7979
return <InputElement placeholder={placeholder}>{element}</InputElement>;
8080
},
8181

8282
focus() {
83-
if (this.$refs.select) {
84-
this.$refs.select.focus();
83+
if (this.select) {
84+
this.select.focus();
8585
}
8686
},
8787

8888
blur() {
89-
if (this.$refs.select) {
90-
this.$refs.select.blur();
89+
if (this.select) {
90+
this.select.blur();
9191
}
9292
},
9393
},
9494

9595
render() {
96-
const { size, prefixCls: customizePrefixCls, optionLabelProp, dataSource, $slots } = this;
96+
const { size, prefixCls: customizePrefixCls, optionLabelProp, dataSource } = this;
9797

9898
const getPrefixCls = this.configProvider.getPrefixCls;
9999
const prefixCls = getPrefixCls('select', customizePrefixCls);
100-
100+
const { class: className } = this.$attrs;
101101
const cls = {
102+
[className]: !!className,
102103
[`${prefixCls}-lg`]: size === 'large',
103104
[`${prefixCls}-sm`]: size === 'small',
104105
[`${prefixCls}-show-search`]: true,
105106
[`${prefixCls}-auto-complete`]: true,
106107
};
107108

108109
let options;
109-
const childArray = filterEmpty($slots.dataSource);
110-
if (childArray.length) {
110+
const childArray = getSlot(this, 'dataSource');
111+
if (childArray.length && isSelectOptionOrSelectOptGroup(childArray[0])) {
111112
options = childArray;
112113
} else {
113114
options = dataSource
@@ -129,28 +130,25 @@ const AutoComplete = {
129130
: [];
130131
}
131132
const selectProps = {
132-
props: {
133-
...getOptionProps(this),
134-
mode: Select.SECRET_COMBOBOX_MODE_DO_NOT_USE,
135-
optionLabelProp,
136-
getInputElement: this.getInputElement,
137-
notFoundContent: getComponentFromProp(this, 'notFoundContent'),
138-
placeholder: '',
139-
},
133+
...getOptionProps(this),
134+
...this.$attrs,
135+
mode: Select.SECRET_COMBOBOX_MODE_DO_NOT_USE,
136+
optionLabelProp,
137+
getInputElement: this.getInputElement,
138+
notFoundContent: getComponent(this, 'notFoundContent'),
139+
placeholder: '',
140140
class: cls,
141-
ref: 'select',
142-
on: getListeners(this),
141+
ref: this.saveSelect,
143142
};
144143
return <Select {...selectProps}>{options}</Select>;
145144
},
146145
};
147146

148147
/* istanbul ignore next */
149-
AutoComplete.install = function(Vue) {
150-
Vue.use(Base);
151-
Vue.component(AutoComplete.name, AutoComplete);
152-
Vue.component(AutoComplete.Option.name, AutoComplete.Option);
153-
Vue.component(AutoComplete.OptGroup.name, AutoComplete.OptGroup);
148+
AutoComplete.install = function(app) {
149+
app.component(AutoComplete.name, AutoComplete);
150+
app.component(AutoComplete.Option.name, AutoComplete.Option);
151+
app.component(AutoComplete.OptGroup.name, AutoComplete.OptGroup);
154152
};
155153

156154
export default AutoComplete;

components/vc-select/util.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export function getPropValue(child, prop) {
3333
return getValuePropValue(child);
3434
}
3535
if (prop === 'children') {
36-
const newChild = cloneElement(getComponent(child));
36+
const temp = getComponent(child);
37+
const newChild = isVNode(temp) ? cloneElement(temp) : temp;
3738
if (isVNode(newChild) && newChild.type === Text) {
3839
return newChild.children;
3940
}

examples/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import '@babel/polyfill';
22
import { createApp } from 'vue';
33
import App from './App.vue';
44
import {
5+
AutoComplete,
56
Radio,
67
Spin,
78
Select,
@@ -49,4 +50,5 @@ app
4950
.use(Row)
5051
.use(Radio)
5152
.use(InputNumber)
53+
.use(AutoComplete)
5254
.mount('#app');

0 commit comments

Comments
 (0)