elementUI之el-select中添加指令

针对控制options中项的可选可不选控制,以及IE下bug梳理

Posted by MSQ on January 2, 2020

新年伊始,扬帆起航,迎接新的挑战!刚刚进入新的迭代,遇见些许让我很棘手的问题,遂记录之。

这是一个项目中常见的需求,el-select为下拉多选,默认值不可删除,或者指定值不可删除。 自己琢磨小半天时间也没有找到一个好的解决办法,看到一篇大佬的文章顿时茅塞顿开,记录一下加深印象 原文地址:https://blog.csdn.net/qq_36356218/article/details/102605332

注意:v-defaultSelect这个是引用的大佬写的main.js或组件内部的Vue.directive定义的方法,第一个值“userId”是select的v-model值,第二个值“options”指的是循环el-option的数组,第三个值“value”记着这个是一个字符串形式传过去的,因为value不像第一个和第二个值是定义过的,第三个值“disabled”也是字符串是指option里边的一个值,我这边默认值是禁止勾选的所以循环options数组的时候给默认值的option加了“disabled:true”,所以最后一个值就当然是“true”了

// v-select
<el-select
	v-model="userId"
	id="selects"
	v-defaultSelect="[userId,options,'value','disabled',true]"
	multiple
	filterable
	allow-create
	default-first-option
	placeholder="请选择"
	:disabled="edits">
	<el-option
		v-for="item in options"
		:key="item.value"
		:disabled="item.disabled"
		:label="item.label"
		:value="item.value">
	</el-option>
</el-select>

main.js中方法也记录了一遍

// main.js
Vue.directive('defaultSelect', {
	componentUpdated (el, bindings, vnode) {
		// values v-model 绑定值
		// options 下拉选项
		// prop 对应 options 中 的 value 属性
		// defaultProp 默认值判断属性
		// defaultValue 默认值判断值
		const [values, options, prop, defaultProp, defaultValue] = bindings.value
		// 需要隐藏的标签索引
		const indexs = []
		const tempData = values.map(a => options.find(op => op[prop] === a))
		tempData.forEach((a, index) => {
		if (a[defaultProp] === defaultValue) indexs.push(index)
		})
		const dealStyle = function (tags) {
		tags.forEach((el, index) => {
			if (indexs.includes(index) && ![...el.classList].includes('select-tag-close-none')) {
			el.classList.add('none')
			}
		})
		}
		// 设置样式 隐藏close icon
		const tags = el.querySelectorAll('.el-tag__close')
		if (tags.length === 0) {
		// 初始化tags为空处理
		setTimeout(() => {
			const tagTemp = el.querySelectorAll('.el-tag__close')
			dealStyle(tagTemp)
		})
		} else {
		dealStyle(tags)
		}
	}
})

完成这些操作以后你会发现你的默认值的close按钮上多了一个none的class,然后css文件或者页面添加!important这个后缀最好是加上的哦,不然可能会被优先级比较高的[class*=” el-icon-“], [class^=el-icon-]{display:inline-block}给冲突掉

css部分
.none{display:none !important;}

这样貌似已经解决了我的问题,但是“万恶的”IE上会有兼容问题(黑人问号)???IE下存在一个无法forEach NodeList的问题。NodeList对象是一个节点的集合,是由Node.childNodes和document.querySelectorAll返回的,实则是一个类数组对象。

Although NodeList is not an Array, it is possible to iterate over it with forEach(). It can also be converted to a real Array using Array.from(). However, some older browsers have not implemented NodeList.forEach() nor Array.from(). This can be circumvented by using Array.prototype.forEach() — see this document’s Example.

在主流浏览器和高版本IE下,可以直接使用forEach进行遍历,但对于IE11以下的版本,无法遍历,下面提供一种对于兼容低版本IE的方法

NodeList.prototype.forEach = Array.prototype.forEach

直接在NodeList对象原型上指定forEach为Array的forEach,从而实现NodeList的forEach遍历。