二次封装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>

效果图:

element upload 封装为组件 elementui封装select_vue.js

element upload 封装为组件 elementui封装select_JSON_02


完。