赞
踩
运行效果
输入2后,模糊查询后,点击全选,选中的是当前筛选后的全部,并不是实际所有下拉选项的全部
此修改时所处情况:当时该系统已经处于迭代更新状态,需求要求将所有多选的下拉选择器都改成支持 模糊查询 全选(是根据模糊查询后 现有匹配项的当前全选) 反选 有编码的还有支持输入编码可以自动匹配选中功能;功能不复杂但是涉及页面很多,所以在能够兼容全局页面的情况下编写了一下代码。
components/selectCheckBox/index.vue
template部分
- // template部分
- <el-select
- v-if="filterableFlag === 'filterable'"
- v-model="selectValue"
- :placeholder="placeholder"
- popper-class="smallSelectDropdown pop_select_down"
- :class="[defaultClass !== 'no' ? 'selectCheckBox' : '', className]"
- :style="style"
- multiple
- clearable
- collapse-tags
- filterable
- reserve-keyword
- :filter-method="filterableHandler"
- @visible-change="selectVisibleChange"
- @change="(v) => selectChange(v, showAll ? options : notAllOptions)"
- >
- <el-checkbox
- v-model="isSelectAll"
- :indeterminate="isIndeterminate"
- class="selectbox"
- style="padding-left:18px"
- @change="selectAllnotAllOptions"
- >全选</el-checkbox
- >
- <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>
- </el-select>
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>
- <span>产品名称:</span>
- <selectCheckBox
- ref="selectCheckBox"
- placeholder="请选择产品代码或名称"
- class-name="filterWidth"
- :model-ori="productCode"
- :options="productCodeList"
- :options-ori="productCodeList"
- opl="label"
- opv="id"
- @selectChange="productNameChange"
- ></selectCheckBox>
-
- // 单独写个change事件 实现子组件的值回传给父组件 给父组件对应值赋值
-
- productNameChange(v) {
- this.productCode = v;
- }
主要是遍历options,根据输入的值 做匹配,代码写的很繁琐,为了适用多用情况加了很多参数和判断,故不附代码;
测试过程中出现的问题:
发现名称不一致,但是编码却相同,所以就导致filter-methods方法报错,(报错内容是关于key未定义),所以在el-option上:key时加了个随机数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。