vue+element-ui 级联选择器 一级元素多选|二级元素单选

记录下自己写的一个小组件,方便以后查阅,写的可能比较简单,如果有更好的写法,希望能分享一下,谢谢!

示例图

在这里插入图片描述

组件使用

 <el-cascader change-on-select @change="selectCascader($event, row)" v-model="row.data" :options="dataList"
                    :props="{ multiple: true, expandTrigger: 'hover' }" collapse-tags></el-cascader>

JS

	 selectCascader(val, row) {
      if (row.his == undefined) {
        row.his = []
      }
      let f = val
      let _this = row  // 行元素,此级联选择器是放在table表格中

      // 新增数据
      if (_this.his.length < f.length) {
        // 和旧数据比,找到新增的数据
        let differenceSet = f.filter(item => {
          let l = _this.his.findIndex(el => el.toString() == item.toString()) == -1
          return l
        })
        let temp = []
        // 遍历(数据可能只有一条数据) 可直接写死
        differenceSet.forEach(el => {
          if (el.length == 2) {  // 判断是否为二级数据
            f.forEach(item => {
              if (el[0] == item[0] && el[1] != item[1]) {
                temp.push(item) // 若有两条相同父级数据,则加入缓存
                return;
              }
            })
          }
        })

        // 去除旧数据
        f = f.filter(item => {
          let l = temp.findIndex(el => el.toString() == item.toString()) == -1 || item.length == 1
          return l
        })

        // 若直接选中二级元素,则将父级元素也添加到列表
        temp = []
        f.forEach(item => {
          if (item.length == 2) { // 判断是否为二级数据
            let l = f.findIndex(el => el.length == 1 && el[0] == item[0] && el != item) == -1
            if (l) {
              temp.push([item[0]])
            }
          }
        })
        // 添加到列表
        temp.forEach(item => {
          f.push(item)
        })
      } else {        // 删减数据
        
        // 和旧数据比,找到删减的数据
        let differenceSet = _this.his.filter(item => {
          let l = f.findIndex(el => el.toString() == item.toString()) == -1
          return l
        })
        // 遍历删除掉的数据(可能只有一条)
        differenceSet.forEach(item => {
          if (item.length == 1) { //若为二级元素则不处理,为一级则删除关联到的二级元素
            f = f.filter(el => el[0].toString() != item[0].toString())
          }
        })
      }
     // 保存到历史记录 和 value
      _this.his = f
      _this.data = f
    }

css部分 由于组件可能缺失部分css,所以从官网复制过来了

.el-cascader-panel>div:first-child .el-checkbox {
  // display: none;
  // pointer-events: none
}

.el-cascader__tags {
  position: absolute;
  left: 0;
  right: 30px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-wrap: wrap;
  line-height: normal;
  text-align: left;
  box-sizing: border-box;

  .el-tag {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    margin: 2px 0 2px 6px;
    text-overflow: ellipsis;
    background: #f0f2f5;
  }
}

.el-icon-remove-outline {
  font-size: 20px;
  color: #F56C6C;
  margin-left: 5px;
  cursor: pointer;
}

.el-icon-circle-plus-outline {
  font-size: 20px;
  color: #909399;
  cursor: pointer;
}

.el-cascader__dropdown .el-scrollbar__wrap {
  overflow: auto;
  height: 100%;
  margin-right: 0 !important;
}
Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐