实现下拉选择器支持全选

运行效果

输入2后,模糊查询后,点击全选,选中的是当前筛选后的全部,并不是实际所有下拉选项的全部

elementUI 自动全选_vue.js


elementUI 自动全选_vue.js_02


此修改时所处情况:当时该系统已经处于迭代更新状态,需求要求将所有多选的下拉选择器都改成支持 模糊查询 全选(是根据模糊查询后 现有匹配项的当前全选) 反选 有编码的还有支持输入编码可以自动匹配选中功能;功能不复杂但是涉及页面很多,所以在能够兼容全局页面的情况下编写了一下代码。

封装组件

components/selectCheckBox/index.vue

template部分

``` // template部分

全选 
<el-option  v-for="item in showAll ? options : notAllOptions"
  :key="item[opv] + '0' + Math.random()"
  :label="item[opl]"
  :value="item[opv]"

  <span class="check" />
  <span>{{ item[opl] }}</span>
</el-option>

```


props从外部接收的参数

 props: { // 父组件的样式名称 defaultClass: { type: String, default: '' }, // 产品名称等支持根据编码自动选中的 不需要传该属性 // 其他需要传 filterableFlag === 'filterable' filterableFlag: { type: String, default: '' }, placeholder: { type: String, default: '' }, // 也是央视名称(因为是多人协作定义时候出现了冲突 导致同功能变量定义重复) className: { type: String, default: '' }, // 因为是兼容的全局 有的页面是单独写的是style style: { type: Object, default: () => {} }, // 下拉选择器的 备选项 options: { type: Array, default: () => [] }, // 对应的el-options的value绑定的字段 opv: { type: String, default: 'id' }, // label绑定的字段 opl: { type: String, default: 'label' }, // 父组件传参过来的下拉备选项的初始数据(options用于子组件绑定) optionsOri: { type: Array, default: () => [] }, // 父组件原来选择器选中的的绑定值 其实和子组件的v-model保持一致 modelOri: { type: Array, default: () => [] } }, 

data watch  methods部分

mounted(离开页面后再返回保留原来的查询条件)

 data() { return { selectValue: [], // 当前子组件 v-model值 isSelectAll: false, // 全选 isIndeterminate: false, // notAllOptions: [], // 模糊查询后产生的新数据 showAll: true // 模糊查询后 是否显示全部备选项 默认为true }; }, watch: { isSelectAll: { handler(val) { this.$emit('selectChange', this.selectValue); } } }, mounted() { if (this.modelOri.length > 0) { this.selectValue = this.modelOri; this.selectCheck(this.selectValue, this.options); } }, methods: { // 根据模糊查询结果 全选 selectAllnotAllOptions(v) { let opArr = this.showAll ? this.options : this.notAllOptions; this.selectValue = v ? opArr.map((item) => item[this.opv]) : []; this.isIndeterminate = false; }, // filterableFlag === 'filterable' 自定义模糊查询 filterableHandler(value) { if (value) { this.showAll = false; this.notAllOptions = []; this.notAllOptions = this.optionsOri.filter((item) => { return ( item[this.opv].indexOf(value) > -1 || item[this.opl].indexOf(value) > -1 ); }); } else { this.showAll = true; } this.selectCheck( this.selectValue, this.showAll ? this.options : this.notAllOptions ); }, // visible-change事件 selectVisibleChange(v) { if (v === false) { this.options = this.optionsOri; this.showAll = true; } this.$emit('selectVisibleChange', v); this.selectCheck( this.selectValue, this.showAll ? this.options : this.notAllOptions ); }, // change事件 selectChange(v, arr) { this.$emit('selectChange', v); // 选中 对应的复选框更改状态,全选根据当前更改状态 this.selectCheck(v, arr); }, // 根据选中数据 更新全选框状态 selectCheck(v, arr) { if (arr.length !== 0) { if (v && v.length === arr.length) { this.selectValue = arr.map((item) => item[this.opv]); this.isSelectAll = true; } else { this.isSelectAll = false; } this.isIndeterminate = v.length > 0 && v.length < arr.length; } } } 


样式补充

 <style lang="scss"> .selectCheckBox .el-tag:first-child { max-width: calc(100% - 72px); .el-select__tags-text { display: inline-block; width: calc(100% - 18px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .el-icon-close { top: -7px; } } </style> <style lang="scss"> .pop_select_down.is-multiple .el-select-dropdown__item { padding: 0 18px; } .pop_select_down.is-multiple .el-select-dropdown__list { padding-top: 0; } .pop_select_down.is-multiple .selectbox { display: block; height: 34px; line-height: 34px; } .pop_select_down.is-multiple .el-select-dropdown__item.selected::after { top: 0.05rem; left: 1.17rem; z-index: 1; font-weight: normal; color: #fff; } .pop_select_down.is-multiple .el-select-dropdown__item .check { position: relative; box-sizing: border-box; display: inline-block; width: 0.875rem; height: 0.875rem; margin-right: 10px; vertical-align: middle; border: 1px solid #656c7e; border-radius: 2px; transition: border-color 0.25s cubic-bezier(0.71, -0.49, 0.26, 1.46), background-color 0.25s cubic-bezier(0.71, -0.49, 0.26, 1.46); } .pop_select_down.is-multiple .el-select-dropdown__item.selected .check { background-color: #656c7e; } </style> 


使用组件

``` 产品名称:

// 单独写个change事件 实现子组件的值回传给父组件 给父组件对应值赋值

productNameChange(v) {
  this.productCode = v;
}

```


#

根据编码自动选中功能

主要是遍历options,根据输入的值 做匹配,代码写的很繁琐,为了适用多用情况加了很多参数和判断,故不附代码;

测试过程中出现的问题: 发现名称不一致,但是编码却相同,所以就导致filter-methods方法报错,(报错内容是关于key未定义),所以在el-option上:key时加了个随机数。