Select下拉选增强 支持快速多选、tooltip等
示例图
1. quicklySelectAll: boolean 在多选模式下支持快速全选取消全选,默认开启
<template>
<div id="app">
<div class="container">
<el-form ref="formRef" :model="formData" :rules="formRules">
<el-form-item prop="selectVal" label="地区">
<Check-All-Select
multiple
:quicklySelectAll="true"
placeholder="请选择地区"
v-model="formData.selectVal"
:optionList="options" />
</el-form-item>
</el-form>
</div>
<el-button @click="submit">提交</el-button>
<el-button @click="reset">重置</el-button>
</div>
</template>
<script lang='ts'>
import Vue from 'vue'
import CheckAllSelect from '@/components/check-all-select'
export default Vue.extend({
name: 'App',
components: {
CheckAllSelect,
},
data () {
return {
formData: {
selectVal: [],
},
formRules: {
selectVal: [
{required: true, message: '请选择'}
]
},
options: [
{ value: 3, label: "普陀" },
{ value: 4, label: "黄埔", disabled: true },
{ value: 5, label: "徐汇" },
{ value: 8, label: "南京", disabled: true },
{ value: 9, label: "苏州" },
{ value: 10, label: "无锡" }
]
}
},
async mounted() {
},
methods: {
submit() {
const _: any = this;
(this.$refs.formRef as any).validate((valid: boolean) => {
if(valid) {
_.$message.success('提交成功')
} else {
_.$message.error('form必填不通过')
}
})
},
reset() {
(this.$refs.formRef as any).resetFields()
}
}
})
</script>
2. tooltip = true 展示选中的值,默认值false
<template>
<Check-All-Select
multiple
tooltip
:quicklySelectAll="true"
placeholder="请选择地区"
v-model="formData.selectVal"
:optionList="options" />
</template>
// 后续示例不展示<script>部分,和第一个示例一致
Attributes
属性名 | 属性类型 | 默认值 | 描述 | 版本 |
---|---|---|---|---|
optionList | [] | - | 下拉选数据源 | - |
quicklySelectAll | boolean | true | 快速选择(仅在多选模式下支持) | - |
tooltip | boolean | false | 是否展值tooltip, 多选以, 分割 | - |
labelKey | string | value | 值对应key | - |
valueKey | string | label | label对应key | - |
disabledKey | string | disabled | disabled对应key | - |
其他同elementUI Select组件属性
源码
<template>
<el-tooltip class="item" :disabled="tooltipDisabledData" effect="dark" :content="tooltipContent" placement="top-start">
<el-select class="check-all-select" v-bind="$attrs" v-model="dataValue" :multiple="multiple">
<el-option v-if="multiple && quicklySelectAll && optionsData.length" key="val_select_all_of_workflow" label="全选" value="">
<div class="div_aaaa" style="width: 100%" @click="handleClickInner">
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll">
全选
</el-checkbox>
</div>
</el-option>
<el-option v-for="item in optionsData" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
</el-select>
</el-tooltip>
</template>
<script>
export default {
name: 'CheckAllSelect',
props: {
value: {
type: [Array, String, Number],
default: '',
},
multiple: {
type: Boolean,
default: false,
},
tooltip: {
type: Boolean,
default: true,
},
// 支持全选-只有在multiple为true下生效
quicklySelectAll: {
type: Boolean,
default: true,
},
optionList: {
type: Array,
default: () => [],
},
labelKey: {
type: String,
default: 'label',
},
valueKey: {
type: String,
default: 'value',
},
disabledKey: {
type: String,
default: 'disabled',
},
},
data() {
return {
checkAll: false,
isIndeterminate: false,
dataValue: '',
};
},
computed: {
optionsData() {
return this.optionList.map(item => {
return {
label: item[this.labelKey],
value: item[this.valueKey],
disabled: item[this.disabledKey] || false,
};
});
},
// 除去 disabled 后可选的
availableOptionsData() {
return this.optionsData.filter(item => !item.disabled);
},
tooltipDisabledData() {
return !this.tooltip || !this.value || (this.multiple && !this.value.length > 0);
},
tooltipContent() {
if (!this.multiple) {
return (this.optionsData.find(i => i.value === this.value) || {}).label || this.value;
} else {
const arr = [];
this.value.forEach(key => {
arr.push((this.optionsData.find(i => i.value === key) || {}).label || key);
});
return arr.join(',');
}
},
},
watch: {
value: {
immediate: true,
handler(neeVal) {
if (this.multiple) {
let checkedCount = neeVal.length;
this.checkAll = checkedCount > 0 && checkedCount === this.availableOptionsData.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.availableOptionsData.length;
}
this.dataValue = neeVal;
},
},
dataValue(newVal) {
this.$emit('input', newVal);
},
},
methods: {
handleClickInner(e) {
this.checkAll = !this.checkAll;
e.preventDefault();
e.stopPropagation();
this.$nextTick(() => {
if (this.checkAll) {
this.dataValue = [...(this.availableOptionsData.map(i => i.value) || [])];
} else {
this.dataValue = [];
}
});
},
},
};
</script>
<style lang="scss" scoped>
.check-all-select {
::v-deep .el-input .el-input__inner {
padding: 0 20px 0 10px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
word-break: normal;
white-space: nowrap;
}
}
</style>