在公司项目研发中,需求提出所有el-select多选下拉框需要增加全选与反选操作,因为前期已经大量使用了select组件 ,无法挨个去单独添加逻辑,所以采用统一封装组件方案,后期一键搜索替换组件名称为自定义组件,在封装时需要保障原绑定的属性以及事件包括插槽slot能够正常使用。
效果图
vue中提供的$attrs可以打印出组件上绑定的所有属性,$listeners可以打印出组件上绑定的所有事件,而$slots可以打印出组件传入的所有插槽
这里遍历插槽$slots,需求只需要多选的select显示按钮,则添加attrs.hasOwnProperty('multiple')&&$attrs.multiple!==false
并且组件插槽具有多个插槽,为了不影响其他插槽使用则限制插槽名称name==='default'
htm部分代码
<el-select v-bind="$attrs" v-on="$listeners" ref="elSelect"><template v-for="(_,name) in $slots" #[name]="scopeData" ><el-optionv-if="name==='default'&&$attrs.hasOwnProperty('multiple')&&$attrs.multiple!==false"disabledclass="multiple-select-handle-option"value="_handle"><el-button size="mini" type="primary" @click="allSelect">全选</el-button><el-button size="mini" @click="reverseSelect">反选</el-button></el-option><slot :name="name" v-bind="scopeData"></slot></template></el-select>
js部分代码
//全选 allSelect() { console.log(this.$slots.default) let arr = this.$slots.default.map(item => item.componentOptions.propsData.value&&!item.componentOptions.propsData.disabled ? item.componentOptions.propsData.value:'').filter(it=>!!it) this.$attrs.value = arr this.$emit('input', arr) this.$emit('change', arr) }, //反选 reverseSelect() { let arr = this.$slots.default.map(item => item.componentOptions.propsData.value&&!item.componentOptions.propsData.disabled ? item.componentOptions.propsData.value:'') this.$attrs.value = arr.filter(item => !this.$attrs.value.includes(item)).filter(it=>!!it) this.$emit('input', this.$attrs.value) this.$emit('change', this.$attrs.value) }
打印this.$slots.defaults 可以获取到每一个option传递的props值,我们主要获取每个option对应value与disable
css部分代码
.multiple-select-handle-option{ height: 40px; }
自定义组件完整代码截图