二次封装el-select组件,以便使用。
包含两个部分:创建、引用。
说明 :
1. 下拉选项框一般是请求数据字典的值以供选择,假设数据字典的接口为’/getDictionary’,请求参数为code,数据字典中的展示值字段为’label’,选中所传值字段为’value’。
2. 也有特定接口请求下拉选择的,需要指定特定的请求接口url、参数和展示的value和label值。
3. 各个属性灵活运用,也可自己添加、更改相关属性配置。
4. 这里设置从父组件中传输过来的对象和数组都用JSON串接收,目的是为了方便监听数值变化。
5. 代码为手写,已检查,但不保证没有单词写错,如报错,请检查一下单词的拼写。
一、创建公共组件vue文件 — comSelect.vue:
<template>
<el-select
v-model="selectValue"
:multiple="multiple"
:disabled="disabled"
:clearable="clearable"
:filterable="filterable"
:placeholder="placeholder"
style="width: 100%"
@change="change"
@visible-change="visibleChange"
>
<el-option
v-for="item in optionLists"
:key="optionKey ? item[optionKey.value] : item.value"
:label="optionKey ? item[optionKey.label] : item.label"
:disabled="isDisabled(item)"
:value="optionKey ? item[optionKey.value] : item.value"
>
<!-- 如果下拉框要显示多个文本,循环’showLabel‘ -->
<span v-if="showLabel.length > 0" class="labelAll">
<span v-for="itemIndex in showLabel" :key="itemIndex+''">{{item[itemIndex]}}</span>
</span>
<span v-else>{{ optionKey ? item[optionKey.value] : item.label }}</span>
</el-option>
</el-select>
</template>
<script>
export default {
name: 'ComSelect',
props: {
value: [String, Array],
options: String, // option选项列表JSON串,如此项有值,则直接用此选项中的数据,不会进行数据请求去获取数据。即优先级options>url。默认为空,非必传。
url: { // 请求下拉框URL地址,默认数据字典请求接口地址,非必传。
type: String,
default: '/getDictionary',
},
urlCode: String, // 请求数据字典时的参数值,若url为数据字典请求地址,则必传,其余情况非必传。
urlParams: String, // 接口其余请求参数的JSON串,非必传。
multiple: { // 是否多选,默认false,非必传。
type: Boolean,
default: false,
},
disabled: { // 是否禁用,默认false,非必传。
type: Boolean,
default: false,
},
clearable: { // 是否可清空选项,默认true,非必传。
type: Boolean,
default: true,
},
filterable: { // 是否可搜索, 默认false,非必传。
type: Boolean,
default: false,
},
placeholder: { // 选择框提示文字,默认‘请选择’,非必传。
type: String,
default: '请选择',
},
optionKeys: String, // 指定显示的vaule和label的key值JSON串,若此项有值,则不再用'value'和'label'作为属性名,以此项设置为准,默认空,非必传。
showLabels: String, // 下拉选项展示值字符串,逗号隔开,若此项有值,则下拉选项所展示文字不再用'label'的值,以此项设置为准,展示时按照顺序展示出来,如展示两个值,则在下拉框中是左右排列,如展示三个值及以上,则第一个和最后一个左右排列,其余值中间分布显示。默认空,非必传。
disables: String, // 禁止选择的属性值,逗号隔开,非必传。
},
data() {
return {
selectValue: this.value,
optionLists: [],
optionKey: null,
requestParams: null,
showLabel: [],
};
},
watch: {
options() {
if (this.options) {
this.optionLists = JSON.parse(this.options)
}
},
urlCode() {
this.getOptions();
},
urlParams() {
this.requestParams = this.urlParams ? JSON.parse(this.urlParams) : null;
this.getOptions();
},
url() {
this.getOptions();
},
value() {
this.selectValue = this.value
},
optionKeys() {
this.optionKey = this.optionKeys ? JSON.parse(this.optionKeys) : null;
},
showLabels() {
this.showLabel = this.showLabels ? this.showLabels.split(',') : [];
},
},
created() {
this.optionKey = this.optionKeys ? JSON.parse(this.optionKeys) : null;
this.showLabel = this.showLabels ? this.showLabels.split(',') : [];
this.requestParams = this.urlParams ? JSON.parse(this.urlParams) : null;
if (this.options) { // 如果父组件有下拉选项数据,则不进行数据请求
this.optionLists = JSON.parse(this.options)
} else {
this.getOptions()
}
},
methods: {
/**
* 获取下拉框的选择项数据
*/
getOptions() {
let params = {}
if (this.urlCode)
params.code = this.urlCode
if(this.requestParams) {
params = Object.assign(params, this.requestParams)
}
this.axios.get(this.url, {params})
.then(res => {
this.optionLists = res.list // 假设返回的数据封装在list中
}).catch(() => {})
},
/**
* 判定该选项是否禁用
* @item {Object} 该选项所有信息所在对象
**/
isDisabled(item) {
if (this.disables) {
const dicList = this.disables.split(',');
const itemValue = this.optionKey ? item[this.optionKey.value] : item.value
const findItemIndex = dicList.findIndex(itemD => itemD === itemValue);
if(findItemIndex > -1)
return true
return false
}
return false
},
/**
* 选择框change事件,将所选值和所选值所在的对象回传给父组件
* @val {String} 当前选中值
**/
change(val) {
let valueKey = 'value'
if (this.optionKey)
valueKey = this.optionKey.value
if (this.multiple) {
const valObjList = [];
val.forEach(element => {
const valObj = this.optionLists.find(itemO => itemO[valueKey] === element);
valObjList.push(valObj)
})
this.$emit('change', val, valObjList)
} else {
const valOption = this.optionLists.filter(itemO => itemO[valueKey] === val);
const [valObj] = valOption;
this.$emit('change', val, valObj);
}
},
/**
* 下拉框出现/隐藏时触发
* @isShow {Boolean} 标识:true为下拉框展开;false为下拉框隐藏
**/
visibleChange(isShow) {
this.$emit('visibleChange', isShow)
},
},
}
</script>
<style lang="less" scoped>
.labelAll {
display: flex;
align-content: center;
justify-content: space-between;
.span:last-child {
font-size: 13px;
color: #8492a6;
}
}
</style>
二、引用:
<template>
<com-select
v-model="model"
:options="options"
:urlParams="urlParams"
:multiple="true"
placeholder="这是placeholder"
:optionKeys="optionKeys"
:showLabels="showLabels"
:disables="disables"
@change="selectChange"
>
</com-select>
</template>
<script>
import comSelect from './comSelect.vue';
export default {
components: { comSelect },
data() {
return {
model: '',
options: JSON.stringify([
{
valueKey: '01',
labelKey: '选项1',
dis: '说明1',
disA: '说明2',
},
{
valueKey: '02',
labelKey: '选项2',
dis: '说明3',
disA: '说明4',
}
]),
urlParams: JSON.stringify({
key1: '01',
key2: 'Y',
}),
optionKeys: JSON.stringify({
value: 'valueKey',
label: 'labelKey'
}),
showLabels: 'labelKey,dis,disA',
disables: '02'
}
},
methods: {
/**
* 选择框选择值更改触发
* @val {String} 当前选中值
* @valObj {Object} 当前选中值所在的对象
**/
selectChange(val, valObj) {
this.model = val
console.log("valObj=>", valObj)
}
},
}
</script>
效果图:
完。