TIPS
问题背景
Element-UI的下拉框只能搜索绑定的 label 字段,需要搜索该条数据的其他字段,比如名称、拼音等
# FilterSelect组件
<template>
<el-select
:value="currentValue"
filterable
:clearable="clearable"
:disabled="disabled"
:placeholder="placeholder"
:filter-method="filterMethod"
default-first-option
@change="$emit('change', $event)"
@foucs="selectFocus"
>
<el-option
v-for="item in filterOptions"
:key="item[optionConfig.value]"
:label="item[optionConfig.label]"
:value="item[optionConfig.value]"
/>
</el-select>
</template>
<script>
export default {
name: "FilterSelect",
model: {
prop: "currentValue",
event: "change"
},
props: {
// 父级的v-model的value
currentValue: [String, Number, Boolean, Array], // eslint-disable-line
clearable: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: "请选择"
},
// 原始的options数据
options: {
type: Array,
default: () => []
},
// 支持搜索的属性名称
filterAttrs: {
type: Array,
default: () => []
},
// options绑定的属性名
optionConfig: {
type: Object,
default: () => {
return { label: "label", value: "value" }
}
},
},
data() {
return {
filterOptions: this.options // 过滤后的options值
}
},
methods: {
toUpperCase(data) {
return String(data).toUpperCase()
},
filterMethod(key) {
const newKey = this.toUpperCase(key)
this.filterOptions = this.options.filter(el => {
let flag = false
this.filterAttrs.forEach(attr => {
if (this.toUpperCase(el[attr]).indexOf(newKey) > -1) {
flag = true
}
})
return flag
})
},
// focus时重置搜索数据
selectFocus() {
this.filterOptions = this.options
}
}
}
</script>
<style lang="scss" scoped>
</style>
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 使用
<template>
<div>
<filter-select
v-model="value"
placeholder="请输入搜索条件"
clearable
:options="options"
:filter-attrs="[ 'name', 'py' ]"
:option-config="{ label: 'name', value: 'code'}"
@change="selectChange"
/>
</div>
</template>
<script>
import FilterSelect from "./FilterSelect"
export default {
name: "index",
components: {
FilterSelect
},
data() {
return {
value: '',
options: [
{ name: '橘子', code: '001', py: 'JZ' },
{ name: '苹果', code: '002', py: 'PG' },
{ name: '香蕉', code: '003', py: 'XJ' },
]
};
},
methods: {
selectChange(val) {
console.log(val)
}
}
};
</script>
<style lang="scss" scoped>
</style>
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
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
# 一个更优雅的写法
TIPS
$attrs会继承除了props接收的其他全部属性,classstyle除外$listeners父级全部监听事件,.native修饰器的除外inheritAttrs: false默认情况下父作用域的不被作为props特性绑定的属性,将会作为普通的 HTML 属性,应用在根元素。设置interitAttrs为 false,之后,不会应用到跟元素上
<template>
<el-select
filterable
:clearable="clearable"
:disabled="disabled"
:placeholder="placeholder"
:filter-method="filterMethod"
default-first-option
v-bind="$attrs"
@focus="selectFocus"
v-on="$listeners"
>
<el-option
v-for="item in filterOptions"
:key="item[optionConfig.value]"
:label="item[optionConfig.label]"
:value="item[optionConfig.value]"
/>
</el-select>
</template>
<script>
export default {
name: "FilterSelect",
inheritAttrs: false,
props: {
clearable: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: "请选择"
},
// 原始的options数据
options: {
type: Array,
default: () => []
},
// 支持搜索的属性名称
filterAttrs: {
type: Array,
default: () => []
},
// options绑定的属性名
optionConfig: {
type: Object,
default: () => {
return { label: "label", value: "value" }
}
},
},
data() {
return {
filterOptions: this.options // 过滤后的options值
}
},
methods: {
toUpperCase(data) {
return String(data).toUpperCase()
},
filterMethod(key) {
const newKey = this.toUpperCase(key)
this.filterOptions = this.options.filter(el => {
let flag = false
this.filterAttrs.forEach(attr => {
if (this.toUpperCase(el[attr]).indexOf(newKey) > -1) {
flag = true
}
})
return flag
})
},
// focus时重置搜索数据
selectFocus() {
this.filterOptions = this.options
}
}
}
</script>
<style lang="scss" scoped>
</style>
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
78
79
80
81
82
83
84
85
86
87
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
78
79
80
81
82
83
84
85
86
87