当前位置:   article > 正文

elementui-select+checkBox实现下拉选择器支持全选_checkbox select

checkbox select

实现下拉选择器支持全选

 

运行效果

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

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

封装组件

components/selectCheckBox/index.vue

template部分

  1. // template部分
  2. <el-select
  3. v-if="filterableFlag === 'filterable'"
  4. v-model="selectValue"
  5. :placeholder="placeholder"
  6. popper-class="smallSelectDropdown pop_select_down"
  7. :class="[defaultClass !== 'no' ? 'selectCheckBox' : '', className]"
  8. :style="style"
  9. multiple
  10. clearable
  11. collapse-tags
  12. filterable
  13. reserve-keyword
  14. :filter-method="filterableHandler"
  15. @visible-change="selectVisibleChange"
  16. @change="(v) => selectChange(v, showAll ? options : notAllOptions)"
  17. >
  18. <el-checkbox
  19. v-model="isSelectAll"
  20. :indeterminate="isIndeterminate"
  21. class="selectbox"
  22. style="padding-left:18px"
  23. @change="selectAllnotAllOptions"
  24. >全选</el-checkbox
  25. >
  26. <el-option
  27. v-for="item in showAll ? options : notAllOptions"
  28. :key="item[opv] + '0' + Math.random()"
  29. :label="item[opl]"
  30. :value="item[opv]"
  31. >
  32. <span class="check" />
  33. <span>{{ item[opl] }}</span>
  34. </el-option>
  35. </el-select>

props从外部接收的参数

  1. props: {
  2. // 父组件的样式名称
  3. defaultClass: {
  4. type: String,
  5. default: ''
  6. },
  7. // 产品名称等支持根据编码自动选中的 不需要传该属性
  8. // 其他需要传 filterableFlag === 'filterable'
  9. filterableFlag: {
  10. type: String,
  11. default: ''
  12. },
  13. placeholder: {
  14. type: String,
  15. default: ''
  16. },
  17. // 也是央视名称(因为是多人协作定义时候出现了冲突 导致同功能变量定义重复)
  18. className: {
  19. type: String,
  20. default: ''
  21. },
  22. // 因为是兼容的全局 有的页面是单独写的是style
  23. style: {
  24. type: Object,
  25. default: () => {}
  26. },
  27. // 下拉选择器的 备选项
  28. options: {
  29. type: Array,
  30. default: () => []
  31. },
  32. // 对应的el-options的value绑定的字段
  33. opv: {
  34. type: String,
  35. default: 'id'
  36. },
  37. // label绑定的字段
  38. opl: {
  39. type: String,
  40. default: 'label'
  41. },
  42. // 父组件传参过来的下拉备选项的初始数据(options用于子组件绑定)
  43. optionsOri: {
  44. type: Array,
  45. default: () => []
  46. },
  47. // 父组件原来选择器选中的的绑定值 其实和子组件的v-model保持一致
  48. modelOri: {
  49. type: Array,
  50. default: () => []
  51. }
  52. },

data watch  methods部分 

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

  1. data() {
  2. return {
  3. selectValue: [], // 当前子组件 v-model值
  4. isSelectAll: false, // 全选
  5. isIndeterminate: false, //
  6. notAllOptions: [], // 模糊查询后产生的新数据
  7. showAll: true // 模糊查询后 是否显示全部备选项 默认为true
  8. };
  9. },
  10. watch: {
  11. isSelectAll: {
  12. handler(val) {
  13. this.$emit('selectChange', this.selectValue);
  14. }
  15. }
  16. },
  17. mounted() {
  18. if (this.modelOri.length > 0) {
  19. this.selectValue = this.modelOri;
  20. this.selectCheck(this.selectValue, this.options);
  21. }
  22. },
  23. methods: {
  24. // 根据模糊查询结果 全选
  25. selectAllnotAllOptions(v) {
  26. let opArr = this.showAll ? this.options : this.notAllOptions;
  27. this.selectValue = v ? opArr.map((item) => item[this.opv]) : [];
  28. this.isIndeterminate = false;
  29. },
  30. // filterableFlag === 'filterable' 自定义模糊查询
  31. filterableHandler(value) {
  32. if (value) {
  33. this.showAll = false;
  34. this.notAllOptions = [];
  35. this.notAllOptions = this.optionsOri.filter((item) => {
  36. return (
  37. item[this.opv].indexOf(value) > -1 ||
  38. item[this.opl].indexOf(value) > -1
  39. );
  40. });
  41. } else {
  42. this.showAll = true;
  43. }
  44. this.selectCheck(
  45. this.selectValue,
  46. this.showAll ? this.options : this.notAllOptions
  47. );
  48. },
  49. // visible-change事件
  50. selectVisibleChange(v) {
  51. if (v === false) {
  52. this.options = this.optionsOri;
  53. this.showAll = true;
  54. }
  55. this.$emit('selectVisibleChange', v);
  56. this.selectCheck(
  57. this.selectValue,
  58. this.showAll ? this.options : this.notAllOptions
  59. );
  60. },
  61. // change事件
  62. selectChange(v, arr) {
  63. this.$emit('selectChange', v);
  64. // 选中 对应的复选框更改状态,全选根据当前更改状态
  65. this.selectCheck(v, arr);
  66. },
  67. // 根据选中数据 更新全选框状态
  68. selectCheck(v, arr) {
  69. if (arr.length !== 0) {
  70. if (v && v.length === arr.length) {
  71. this.selectValue = arr.map((item) => item[this.opv]);
  72. this.isSelectAll = true;
  73. } else {
  74. this.isSelectAll = false;
  75. }
  76. this.isIndeterminate = v.length > 0 && v.length < arr.length;
  77. }
  78. }
  79. }

样式补充

  1. <style lang="scss">
  2. .selectCheckBox .el-tag:first-child {
  3. max-width: calc(100% - 72px);
  4. .el-select__tags-text {
  5. display: inline-block;
  6. width: calc(100% - 18px);
  7. overflow: hidden;
  8. text-overflow: ellipsis;
  9. white-space: nowrap;
  10. }
  11. .el-icon-close {
  12. top: -7px;
  13. }
  14. }
  15. </style>
  16. <style lang="scss">
  17. .pop_select_down.is-multiple .el-select-dropdown__item {
  18. padding: 0 18px;
  19. }
  20. .pop_select_down.is-multiple .el-select-dropdown__list {
  21. padding-top: 0;
  22. }
  23. .pop_select_down.is-multiple .selectbox {
  24. display: block;
  25. height: 34px;
  26. line-height: 34px;
  27. }
  28. .pop_select_down.is-multiple .el-select-dropdown__item.selected::after {
  29. top: 0.05rem;
  30. left: 1.17rem;
  31. z-index: 1;
  32. font-weight: normal;
  33. color: #fff;
  34. }
  35. .pop_select_down.is-multiple .el-select-dropdown__item .check {
  36. position: relative;
  37. box-sizing: border-box;
  38. display: inline-block;
  39. width: 0.875rem;
  40. height: 0.875rem;
  41. margin-right: 10px;
  42. vertical-align: middle;
  43. border: 1px solid #656c7e;
  44. border-radius: 2px;
  45. transition: border-color 0.25s cubic-bezier(0.71, -0.49, 0.26, 1.46),
  46. background-color 0.25s cubic-bezier(0.71, -0.49, 0.26, 1.46);
  47. }
  48. .pop_select_down.is-multiple .el-select-dropdown__item.selected .check {
  49. background-color: #656c7e;
  50. }
  51. </style>

使用组件

  1. <span>产品名称:</span>
  2. <selectCheckBox
  3. ref="selectCheckBox"
  4. placeholder="请选择产品代码或名称"
  5. class-name="filterWidth"
  6. :model-ori="productCode"
  7. :options="productCodeList"
  8. :options-ori="productCodeList"
  9. opl="label"
  10. opv="id"
  11. @selectChange="productNameChange"
  12. ></selectCheckBox>
  13. // 单独写个change事件 实现子组件的值回传给父组件 给父组件对应值赋值
  14. productNameChange(v) {
  15. this.productCode = v;
  16. }

根据编码自动选中功能

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/107304
推荐阅读