基于Vue和Element-UI自定义分组以及分组全选Select 选择器

这篇具有很好参考价值的文章主要介绍了基于Vue和Element-UI自定义分组以及分组全选Select 选择器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Vue和Element-UI自定义分组以及分组全选Select 选择器

上一篇博文我们已经实现了基于Vue和Element-UI中Select 选择器的分组全选以及样式修改问题, 但是在分组方面我们是用了element-ui 自带的使用el-option-group对备选项进行分组,它的label属性为分组名的功能,但是出来的效果样式很难自定义,就算是魔改element的样式也有一些改不了的。

比如我们的需求就是需要把分组全选框移动到分组名旁边,然后还需要对选项进行列对齐

基于Vue和Element-UI自定义分组以及分组全选Select 选择器

那我们最终需要实现的效果就是

基于Vue和Element-UI自定义分组以及分组全选Select 选择器

并优化了一些文字过长的样式问题。

话不多说,具体的问题我们在上一篇博文也都讲到了,感兴趣的可以移至上一篇博文查看。下面我们直接来看代码吧

<template>
  <div>
    <el-select v-model="value" placeholder="请选择" @change="changeSelect" style="width: 250px"  clearable multiple collapse-tags size="small"
               popper-class="productGroupSelector" class="productGroup-select">
        <div v-for="group in options" :key="group.label" class="productGroupSelector-group">
          <div style="display: flex;align-items: center; padding-top: 8px; padding-left: 5px">
            <el-checkbox v-model="group.checked" @change='selectAll($event,group.id)' :indeterminate="group.isIndeterminate"></el-checkbox>
            <div class="productGroupSelector-group-title">{{group.label}}</div>
          </div>
          <div style="display: flex; align-items: start;">
            <div style="width: 400px">
              <el-option class="productGroupSelector-option"
                         v-for="item in group.options"
                         :key="item.value"
                         :label="item.label"
                         :value="group.label + '-' + item.value">
                <div class="productGroupSelector-option-content">{{ item.label }}</div>
              </el-option>
            </div>
          </div>
        </div>
    </el-select>
  </div>
</template>
<script>
export default {
  name: 'SelectorComponent2',
  data () {
    return {
      options: [{
        id: 1,
        label: '热门城市',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Shanghai',
          label: '上海'
        }, {
          value: 'Beijing',
          label: '北京'
        }]
      }, {
        id: 2,
        label: '城市名',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu',
          label: '成都'
        }, {
          value: 'Shenzhen',
          label: '深圳'
        }, {
          value: 'Guangzhou',
          label: '广州'
        }, {
          value: 'Dalian',
          label: '大连'
        },
        {
          value: 'Huizhou',
          label: '惠州'
        }]
      },
      {
        id: 3,
        label: '城市名2',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu2',
          label: '成都22222'
        }, {
          value: 'Shenzhen2',
          label: '深圳22222'
        }, {
          value: 'Guangzhou2',
          label: '广州2222'
        }, {
          value: 'Dalian2',
          label: '大连222222222222'
        },
        {
          value: 'Huizhou2',
          label: '惠州2'
        }]
      },
      {
        id: 4,
        label: '城市名3',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu3',
          label: '成都333'
        }, {
          value: 'Shenzhen3',
          label: '深圳3'
        }, {
          value: 'Guangzhou3',
          label: '广州33'
        }, {
          value: 'Dalian3',
          label: '大连33333111111111111111333'
        },
        {
          value: 'Huizhou3',
          label: '惠州3'
        }]
      }],
      value: ''
    }
  },
  methods: {
    onChange (value) {
      console.log(value)
      console.log(this.value)
    },
    selectAll (val, id) {
      const selectOption = this.options.find(f => f.id === id)
      const arr = selectOption.options.map(m => selectOption.label + '-' + m.value)
      if (val) {
        arr.forEach(item => {
          if (!this.value.includes(item)) {
            this.value.push(item)
          }
        })
      } else {
        this.value.forEach((item, index) => {
          if (arr.includes(item)) {
            this.value.splice(index, 1, '')
          }
        })
      }
      this.value = this.value.filter(f => f !== '')
      if (selectOption.checked) {
        selectOption.isIndeterminate = false
      }
    },
    changeSelect (val) {
      this.options.forEach(item => {
        const arr = item.options.map(m => item.label + '-' + m.value)
        item.isIndeterminate = arr.some((v) => {
          return val.some(s => s === v)
        })
        item.checked = arr.every((v) => {
          return val.some(s => s === v)
        })
        if (item.checked) {
          item.isIndeterminate = false
        }
      })
    }
  }
}
</script>

<style lang="less" scoped>

.productGroupSelector-group {
  padding-top: 10px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  width: 400px;
  padding-bottom: 10px;
  &-title {
    padding-left: 5px;
    font-weight:bold
  }
  &:after {
    display: none;
  }
}

.productGroupSelector-option {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  width: 200px;
  &-content {
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
  }
}

.productGroup-select /deep/ .el-select__tags-text:first-child{
  max-width: 120px;
}

</style>

<style lang="less">
.productGroupSelector {
  .el-scrollbar__view.el-select-dropdown__list {
    width: 800px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    padding-top: 0;
    overflow-x: hidden;
  }
}
.productGroupSelector {
  .el-select-dropdown__wrap.el-scrollbar__wrap {
    max-height: 350px
  }
}

</style>

再进一步优化,自适应浏览器,当浏览器窗口变化的时候,下拉框的内容能够自适应

<template>
  <div>
    <el-select v-model="value" placeholder="请选择" @change="changeSelect" style="width: 250px"  clearable multiple collapse-tags size="small"
               popper-class="productGroupSelector" class="productGroup-select">
        <div v-for="group in options" :key="group.label" class="productGroupSelector-group">
          <div style="display: flex;align-items: center; padding-top: 8px; padding-left: 5px">
            <el-checkbox v-model="group.checked" @change='selectAll($event,group.id)' :indeterminate="group.isIndeterminate"></el-checkbox>
            <div class="productGroupSelector-group-title">{{group.label}}</div>
          </div>
          <div style="display: flex; align-items: start;">
            <div class="productGroupSelector-option-root">
              <el-option class="productGroupSelector-option"
                         v-for="item in group.options"
                         :key="item.value"
                         :label="item.label"
                         :value="group.label + '-' + item.value">
                <div class="productGroupSelector-option-content">{{ item.label }}</div>
              </el-option>
            </div>
          </div>
        </div>
    </el-select>
  </div>
</template>
<script>
export default {
  name: 'SelectorComponent3',
  data () {
    return {
      options: [{
        id: 1,
        label: '热门城市',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Shanghai',
          label: '上海'
        }, {
          value: 'Beijing',
          label: '北京'
        }]
      }, {
        id: 2,
        label: '城市名',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu',
          label: '成都'
        }, {
          value: 'Shenzhen',
          label: '深圳'
        }, {
          value: 'Guangzhou',
          label: '广州'
        }, {
          value: 'Dalian',
          label: '大连'
        },
        {
          value: 'Huizhou',
          label: '惠州'
        }]
      },
      {
        id: 3,
        label: '城市名2',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu2',
          label: '成都22222'
        }, {
          value: 'Shenzhen2',
          label: '深圳22222'
        }, {
          value: 'Guangzhou2',
          label: '广州2222'
        }, {
          value: 'Dalian2',
          label: '大连222222222222'
        },
        {
          value: 'Huizhou2',
          label: '惠州2'
        }]
      },
      {
        id: 4,
        label: '城市名3',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu3',
          label: '成都333'
        }, {
          value: 'Shenzhen3',
          label: '深圳3'
        }, {
          value: 'Guangzhou3',
          label: '广州33'
        }, {
          value: 'Dalian3',
          label: '大连33333111111111111111333'
        },
        {
          value: 'Huizhou3',
          label: '惠州3'
        }]
      }],
      value: ''
    }
  },
  methods: {
    selectAll (val, id) {
      const selectOption = this.options.find(f => f.id === id)
      const arr = selectOption.options.map(m => selectOption.label + '-' + m.value)
      if (val) {
        arr.forEach(item => {
          if (!this.value.includes(item)) {
            this.value.push(item)
          }
        })
      } else {
        this.value.forEach((item, index) => {
          if (arr.includes(item)) {
            this.value.splice(index, 1, '')
          }
        })
      }
      this.value = this.value.filter(f => f !== '')
      if (selectOption.checked) {
        selectOption.isIndeterminate = false
      }
    },
    changeSelect (val) {
      this.options.forEach(item => {
        const arr = item.options.map(m => item.label + '-' + m.value)
        item.isIndeterminate = arr.some((v) => {
          return val.some(s => s === v)
        })
        item.checked = arr.every((v) => {
          return val.some(s => s === v)
        })
        if (item.checked) {
          item.isIndeterminate = false
        }
      })
    }
  }
}
</script>

<style lang="less" scoped>
@selectGroupWidth: 400px;
.productGroupSelector-group {
  padding-top: 10px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  width: @selectGroupWidth;
  padding-bottom: 10px;
  &-title {
    padding-left: 5px;
    font-weight:bold
  }
  &:after {
    display: none;
  }
}

.productGroupSelector-option-root {
  width: @selectGroupWidth;
}

.productGroupSelector-option {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  width: (@selectGroupWidth / 2);
  &-content {
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
  }
}

.productGroup-select /deep/ .el-select__tags-text:first-child{
  max-width: 120px;
}

</style>

<style lang="less">
@selectWidth: 800px;
.productGroupSelector {
  .el-scrollbar__view.el-select-dropdown__list {
    width: @selectWidth;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    padding-top: 0;
    @media screen and (max-width: @selectWidth) {
      width: (@selectWidth/2);
    }
  }
}
.productGroupSelector {
  .el-select-dropdown__wrap.el-scrollbar__wrap {
    max-height: 350px
  }
}

</style>

效果如下:

基于Vue和Element-UI自定义分组以及分组全选Select 选择器

(更新于2022年4月1日)

更新了一下样式

<template>
  <div>
    <el-select v-model="value" placeholder="请选择" @change="changeSelect" style="width: 250px"  clearable multiple collapse-tags size="small"
               popper-class="productGroupSelector" class="productGroup-select">
        <div v-for="group in options" :key="group.label" class="productGroupSelector-group">
          <div style="display: flex;align-items: center; padding-top: 8px; padding-left: 5px">
            <el-checkbox v-model="group.checked" @change='selectAll($event,group.id)' :indeterminate="group.isIndeterminate"></el-checkbox>
            <div class="productGroupSelector-group-title">{{group.label}}</div>
          </div>
          <div style="display: flex; align-items: start;">
            <div class="productGroupSelector-option-root">
              <el-option class="productGroupSelector-option"
                         v-for="item in group.options"
                         :key="item.value"
                         :label="item.label"
                         :value="group.label + '-' + item.value">
                <div class="productGroupSelector-option-content">{{ item.label }}</div>
              </el-option>
            </div>
          </div>
        </div>
    </el-select>
  </div>
</template>
<script>
export default {
  name: 'SelectorComponent4',
  data () {
    return {
      options: [{
        id: 1,
        label: '热门城市',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Shanghai',
          label: '上海'
        }, {
          value: 'Beijing',
          label: '北京'
        }]
      }, {
        id: 2,
        label: '城市名',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu',
          label: '成都'
        }, {
          value: 'Shenzhen',
          label: '深圳'
        }, {
          value: 'Guangzhou',
          label: '广州'
        }, {
          value: 'Dalian',
          label: '大连'
        },
        {
          value: 'Huizhou',
          label: '惠州'
        }]
      },
      {
        id: 3,
        label: '城市名2',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu2',
          label: '成都22222'
        }, {
          value: 'Shenzhen2',
          label: '深圳22222'
        }, {
          value: 'Guangzhou2',
          label: '广州2222'
        }, {
          value: 'Dalian2',
          label: '大连222222222222'
        },
        {
          value: 'Huizhou2',
          label: '惠州2'
        }]
      },
      {
        id: 4,
        label: '城市名3',
        checked: false,
        isIndeterminate: false,
        options: [{
          value: 'Chengdu3',
          label: '成都333'
        }, {
          value: 'Shenzhen3',
          label: '深圳3'
        }, {
          value: 'Guangzhou3',
          label: '广州33'
        }, {
          value: 'Dalian3',
          label: '大连33333111111111111111333'
        },
        {
          value: 'Huizhou3',
          label: '惠州3'
        }]
      }],
      value: ''
    }
  },
  methods: {
    selectAll (val, id) {
      const selectOption = this.options.find(f => f.id === id)
      const arr = selectOption.options.map(m => selectOption.label + '-' + m.value)
      if (val) {
        arr.forEach(item => {
          if (!this.value.includes(item)) {
            this.value.push(item)
          }
        })
      } else {
        this.value.forEach((item, index) => {
          if (arr.includes(item)) {
            this.value.splice(index, 1, '')
          }
        })
      }
      this.value = this.value.filter(f => f !== '')
      if (selectOption.checked) {
        selectOption.isIndeterminate = false
      }
    },
    changeSelect (val) {
      this.options.forEach(item => {
        const arr = item.options.map(m => item.label + '-' + m.value)
        item.isIndeterminate = arr.some((v) => {
          return val.some(s => s === v)
        })
        item.checked = arr.every((v) => {
          return val.some(s => s === v)
        })
        if (item.checked) {
          item.isIndeterminate = false
        }
      })
    }
  }
}
</script>

<style lang="less" scoped>
@selectGroupWidth: 450px;
.productGroupSelector-group {
  padding-top: 10px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  width: @selectGroupWidth;
  padding-bottom: 10px;
  &-title {
    padding-left: 5px;
    font-weight:bold
  }
  &:after {
    display: none;
  }
}

.productGroupSelector-option-root {
  width: @selectGroupWidth;
}

.el-select-dropdown.is-multiple .el-select-dropdown__item{
  padding-right: 0;
}

.el-select-dropdown.is-multiple .el-select-dropdown__item.selected:after{
  left: 5px;
}

.productGroup-select /deep/ .el-select__tags-text:first-child{
  max-width: 120px;
}

.productGroupSelector-option {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  width: (@selectGroupWidth / 3);
  &-content {
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
  }
}

.productGroup-select /deep/ .el-select__tags-text:first-child{
  max-width: 120px;
}

</style>

<style lang="less">
@selectWidth: 900px;
.productGroupSelector {
  .el-scrollbar__view.el-select-dropdown__list {
    width: @selectWidth;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    padding-top: 0;
    @media screen and (max-width: @selectWidth) {
      width: (@selectWidth/2);
    }
  }
}
.productGroupSelector {
  .el-select-dropdown__wrap.el-scrollbar__wrap {
    max-height: 350px
  }
}

</style>

基于Vue和Element-UI自定义分组以及分组全选Select 选择器

源代码

https://gitee.com/cckevincyh/vue-elementui文章来源地址https://www.toymoban.com/news/detail-405202.html

到了这里,关于基于Vue和Element-UI自定义分组以及分组全选Select 选择器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包