Skip to content

Commit 3e8e90d

Browse files
committed
perf: update select
1 parent 147f153 commit 3e8e90d

File tree

13 files changed

+232
-72
lines changed

13 files changed

+232
-72
lines changed

build/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
22
dev: {
3-
componentName: 'steps', // dev components
3+
componentName: 'select', // dev components
44
},
55
};

components/select/__tests__/__snapshots__/demo.test.js.snap

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ exports[`renders ./components/select/demo/custom-dropdown-menu.md correctly 1`]
6363
<div tabindex="0" class="ant-select ant-select-enabled" style="width: 120px;">
6464
<div role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="test-uuid" class="ant-select-selection ant-select-selection--single">
6565
<div class="ant-select-selection__rendered">
66-
<div title="Lucy" class="ant-select-selection-selected-value" style="display: block; opacity: 1;">Lucy</div>
66+
<div title="lucy" class="ant-select-selection-selected-value" style="display: block; opacity: 1;">lucy</div>
6767
</div><span unselectable="on" class="ant-select-arrow" style="user-select: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span>
6868
</div>
6969
</div>
@@ -125,6 +125,24 @@ exports[`renders ./components/select/demo/optgroup.md correctly 1`] = `
125125
</div>
126126
`;
127127
128+
exports[`renders ./components/select/demo/option-label-prop.md correctly 1`] = `
129+
<div tabindex="0" class="ant-select ant-select-enabled" style="width: 100%;">
130+
<div role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="test-uuid" class="ant-select-selection ant-select-selection--multiple">
131+
<div class="ant-select-selection__rendered">
132+
<div unselectable="on" class="ant-select-selection__placeholder" style="display: none; user-select: none;">select one country</div>
133+
<div>
134+
<li unselectable="on" role="presentation" title="China" class="ant-select-selection__choice" style="user-select: none;">
135+
<div class="ant-select-selection__choice__content">China</div><span class="ant-select-selection__choice__remove"><i aria-label="icon: close" class="ant-select-remove-icon anticon anticon-close"><svg viewBox="64 64 896 896" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></i></span>
136+
</li>
137+
<li class="ant-select-search ant-select-search--inline">
138+
<div class="ant-select-search__field__wrap"><input autocomplete="off" value="" class="ant-select-search__field"><span class="ant-select-search__field__mirror">&nbsp;</span></div>
139+
</li>
140+
</div>
141+
</div>
142+
</div>
143+
</div>
144+
`;
145+
128146
exports[`renders ./components/select/demo/options.md correctly 1`] = `
129147
<div tabindex="0" class="ant-select ant-select-enabled" style="width: 120px;">
130148
<div role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="test-uuid" class="ant-select-selection ant-select-selection--single">

components/select/__tests__/index.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { asyncExpect } from '@/tests/utils';
33
import Select from '..';
44
import Icon from '../../icon';
55
import focusTest from '../../../tests/shared/focusTest';
6+
import mountTest from '../../../tests/shared/mountTest';
67

78
describe('Select', () => {
89
focusTest(Select);
10+
mountTest(Select);
911

1012
it('should have default notFoundContent', async () => {
1113
const wrapper = mount(Select, {

components/select/demo/custom-dropdown-menu.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,27 @@ Customize the dropdown menu via `dropdownRender`.
1414
<div slot="dropdownRender" slot-scope="menu">
1515
<v-nodes :vnodes="menu" />
1616
<a-divider style="margin: 4px 0;" />
17-
<div style="padding: 8px; cursor: pointer;"><a-icon type="plus" /> Add item</div>
17+
<div style="padding: 4px 8px; cursor: pointer;" @mousedown="e => e.preventDefault()" @click="addItem"><a-icon type="plus" /> Add item</div>
1818
</div>
19-
<a-select-option value="jack">Jack</a-select-option>
20-
<a-select-option value="lucy">Lucy</a-select-option>
19+
<a-select-option v-for="item in items" :value="item" :key="item">{{item}}</a-select-option>
2120
</a-select>
2221
</template>
2322
<script>
23+
let index = 0;
2424
export default {
25-
data: () => ({ console: console }),
25+
data: () => ({ items: ['jack', 'lucy'] }),
2626
components: {
2727
VNodes: {
2828
functional: true,
2929
render: (h, ctx) => ctx.props.vnodes,
3030
},
3131
},
32+
methods: {
33+
addItem() {
34+
console.log('addItem');
35+
this.items.push(`New item ${index++}`)
36+
}
37+
}
3238
};
3339
</script>
3440
```

components/select/demo/index.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import SelectUsers from './select-users';
1313
import Suffix from './suffix';
1414
import HideSelected from './hide-selected';
1515
import CustomDropdownMenu from './custom-dropdown-menu';
16+
import OptionLabelProp from './option-label-prop';
1617
1718
import CN from '../index.zh-CN.md';
1819
import US from '../index.en-US.md';
@@ -54,6 +55,7 @@ export default {
5455
<Suffix />
5556
<HideSelected />
5657
<CustomDropdownMenu />
58+
<OptionLabelProp />
5759
<api>
5860
<CN slot="cn" />
5961
<US />
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<cn>
2+
#### 定制回填内容
3+
使用 `optionLabelProp` 指定回填到选择框的 `Option` 属性。
4+
</cn>
5+
6+
<us>
7+
#### Custom selection render
8+
Spacified the prop name of Option which will be rendered in select box.
9+
</us>
10+
11+
```tpl
12+
<template>
13+
<a-select
14+
mode="multiple"
15+
style="width: 100%"
16+
placeholder="select one country"
17+
v-model="value"
18+
optionLabelProp="label"
19+
>
20+
<a-select-option value="china" label="China">
21+
<span role="img" aria-label="China">
22+
🇨🇳
23+
</span>
24+
China (中国)
25+
</a-select-option>
26+
<a-select-option value="usa" label="USA">
27+
<span role="img" aria-label="USA">
28+
🇺🇸
29+
</span>
30+
USA (美国)
31+
</a-select-option>
32+
<a-select-option value="japan" label="Japan">
33+
<span role="img" aria-label="Japan">
34+
🇯🇵
35+
</span>
36+
Japan (日本)
37+
</a-select-option>
38+
<a-select-option value="korea" label="Korea">
39+
<span role="img" aria-label="Korea">
40+
🇰🇷
41+
</span>
42+
Korea (韩国)
43+
</a-select-option>
44+
</a-select>
45+
</template>
46+
<script>
47+
export default {
48+
data(){
49+
return {
50+
value: ['china']
51+
}
52+
},
53+
watch: {
54+
value(val) {
55+
console.log(`selected:`, val);
56+
},
57+
},
58+
};
59+
</script>
60+
```

components/select/index.en-US.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
| dropdownMatchSelectWidth | Whether dropdown's width is same with select. | boolean | true |
2121
| dropdownRender | Customize dropdown content | (menuNode: VNode, props) => VNode | - |
2222
| dropdownStyle | style of dropdown menu | object | - |
23+
| dropdownMenuStyle | additional style applied to dropdown menu | object | - |
2324
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true |
2425
| firstActiveValue | Value of action option by default | string\|string\[] | - |
2526
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | function(triggerNode) | () => document.body |
@@ -85,3 +86,9 @@
8586
| -------- | ----------- | ------------ | ------- |
8687
| key | | string | - |
8788
| label | Group label | string\|slot | - |
89+
90+
## FAQ
91+
92+
### The dropdown is closed when click `dropdownRender` area?
93+
94+
See the [dropdownRender example](/components/select/#components-select-demo-custom-dropdown).

components/select/index.jsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,13 @@ const Select = {
118118
created() {
119119
warning(
120120
this.$props.mode !== 'combobox',
121+
'Select',
121122
'The combobox mode of Select is deprecated,' +
122123
'it will be removed in next major version,' +
123124
'please use AutoComplete instead',
124125
);
125126
},
126127
methods: {
127-
savePopupRef(ref) {
128-
this.popupRef = ref;
129-
},
130-
focus() {
131-
this.$refs.vcSelect.focus();
132-
},
133-
blur() {
134-
this.$refs.vcSelect.blur();
135-
},
136128
getNotFoundContent(renderEmpty) {
137129
const h = this.$createElement;
138130
const notFoundContent = getComponentFromProp(this, 'notFoundContent');
@@ -144,6 +136,16 @@ const Select = {
144136
}
145137
return renderEmpty(h, 'Select');
146138
},
139+
savePopupRef(ref) {
140+
this.popupRef = ref;
141+
},
142+
focus() {
143+
this.$refs.vcSelect.focus();
144+
},
145+
blur() {
146+
this.$refs.vcSelect.blur();
147+
},
148+
147149
isCombobox() {
148150
const { mode } = this;
149151
return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE;
@@ -171,6 +173,7 @@ const Select = {
171173
mode,
172174
options,
173175
getPopupContainer,
176+
showArrow,
174177
...restProps
175178
} = getOptionProps(this);
176179

@@ -198,6 +201,7 @@ const Select = {
198201
const cls = {
199202
[`${prefixCls}-lg`]: size === 'large',
200203
[`${prefixCls}-sm`]: size === 'small',
204+
[`${prefixCls}-show-arrow`]: showArrow,
201205
};
202206

203207
let { optionLabelProp } = this.$props;
@@ -234,6 +238,7 @@ const Select = {
234238
removeIcon: finalRemoveIcon,
235239
clearIcon: finalClearIcon,
236240
menuItemSelectedIcon: finalMenuItemSelectedIcon,
241+
showArrow,
237242
...rest,
238243
...modeConfig,
239244
prefixCls,

components/select/index.zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true |
2121
| dropdownRender | 自定义下拉框内容 | (menuNode: VNode, props) => VNode | - |
2222
| dropdownStyle | 下拉菜单的 style 属性 | object | - |
23+
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - |
2324
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`| boolean or function(inputValue, option) | true |
2425
| firstActiveValue | 默认高亮的选项 | string\|string\[] | - |
2526
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body |
@@ -86,3 +87,9 @@
8687
| ----- | ---- | --------------------------- | ------ |
8788
| key | | string | - |
8889
| label | 组名 | string\|\|function(h)\|slot ||
90+
91+
## FAQ
92+
93+
### 点击 `dropdownRender` 里的内容浮层关闭怎么办?
94+
95+
看下 [dropdownRender 例子](/components/select-cn/#components-select-demo-custom-dropdown) 里的说明。

components/vc-select/DropdownMenu.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default {
3737
},
3838

3939
created() {
40-
this.rafInstance = { cancel: () => null };
40+
this.rafInstance = null;
4141
this.lastInputValue = this.$props.inputValue;
4242
this.lastVisible = false;
4343
},
@@ -60,8 +60,8 @@ export default {
6060
this.prevVisible = this.visible;
6161
},
6262
beforeDestroy() {
63-
if (this.rafInstance && this.rafInstance.cancel) {
64-
this.rafInstance.cancel();
63+
if (this.rafInstance) {
64+
raf.cancel(this.rafInstance);
6565
}
6666
},
6767
methods: {

0 commit comments

Comments
 (0)