vue element 实现 多个单选、分类联动。类似级联选择器(1)

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

<div id="app">
<el-form size="medium" label-width="85px" class="retail-form" label-position="right">
        <el-form-item v-for="(item, index) in allData" :key="index" label="产品类别:">
          <el-radio-group v-model="item.radio" @change="classChange($event,item)">
            <el-radio-button :label="0">全部</el-radio-button>
            <el-radio-button v-for="(childItem, childIndex) in item.value" :key="childIndex" :label="childItem.Id">{{ childItem.Name }}</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-for="(leveItem, leveIndex) in levelArr" v-if="leveItem.children" :key="leveIndex" label="产品级别">
          <el-radio-group v-model="leveItem.radio" @change="deepLevelChange($event, leveItem, leveIndex)">
            <el-radio-button :label="0">全部{{ leveItem.radio }}</el-radio-button>
            <el-radio-button v-for="(childItem, childIndex) in leveItem.children" :key="childIndex" :label="childItem.Id">{{ childItem.Name }}</el-radio-button>
          </el-radio-group>
        </el-form-item>
      </el-form>
</div>
var Main = {
  data() {
    return {
      allData: [
        { 'Id': 1, 'Pid': 0, 'Name': 'CCCF自愿1', 'Dep': 7, 'Level': 1, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 2, 'Pid': 0, 'Name': 'CCCF自愿2', 'Dep': 9, 'Level': 1, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 3, 'Pid': 0, 'Name': 'CCCF自愿3', 'Dep': 8, 'Level': 1, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 4, 'Pid': 1, 'Name': '防火材料', 'Dep': 7, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 5, 'Pid': 1, 'Name': '建筑耐火', 'Dep': 7, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 6, 'Pid': 1, 'Name': '消防防烟排烟', 'Dep': 7, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 7, 'Pid': 2, 'Name': '防火材料', 'Dep': 9, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 8, 'Pid': 2, 'Name': '建筑耐火构件', 'Dep': 9, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 9, 'Pid': 2, 'Name': '消防防烟排烟', 'Dep': 9, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 10, 'Pid': 3, 'Name': '消防防烟排烟', 'Dep': 8, 'Level': 2, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 11, 'Pid': 4, 'Name': '测试第三级1', 'Dep': 8, 'Level': 3, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 12, 'Pid': 5, 'Name': '测试第三级2', 'Dep': 8, 'Level': 3, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 13, 'Pid': 6, 'Name': '测试第三级3', 'Dep': 8, 'Level': 3, 'Remark': null, 'Sort': null, 'reserve_1': null },
        { 'Id': 14, 'Pid': 7, 'Name': '测试第三级4', 'Dep': 8, 'Level': 3, 'Remark': null, 'Sort': null, 'reserve_1': null }
      ],
      levelArr: []
    }
  },
  mounted() {
    this.allData = this.joinLevel(this.allData)
  },methods: {
    classChange(e, item) {
      console.log(e, '这个列表需要的id')
      console.log(item.radio, 'item')
      // 重置leveItem.radio
      // 点击第一层单独处理
      // 清空LevelArr
      if (item.radio !== 0) {
        this.levelArr = []
        // 拿到对应的第几个
        this.levelArr.splice(0, 1, item.value.filter(items => {
          items.radio = 0
          return `${items.Id}` === `${item.radio}`
        })[0])
      } else {
        this.levelArr = []
      }
      this.$forceUpdate()
      console.log(this.levelArr, 'levelArr')
    },
    deepLevelChange(e, item, index) {
      console.log(item.radio, '这个列表需要的id')
      // console.log(index, '这个item所处于LevelArr的下标')
      // 这里就去改对应的levelArr的index往后的一个的位置
      if (item.radio !== 0) {
        const cuttentItem = item.children.filter(items => {
          return `${items.Id}` === `${item.radio}`
        })[0]

        if (cuttentItem) {
          cuttentItem.radio = 0
          this.levelArr.splice(index + 1, 1, cuttentItem)
        }
      } else {
        this.levelArr = this.levelArr.slice(0, index + 1)
      }
      this.$forceUpdate()
    },
    // 这是整理数据格式变成好判断的格式
    joinLevel(data) {
      const result = []
      const map = {}
      // 声明一个对象拿来装分组
      data.map(item => {
        // 遍历数组
        if (!map[`${item.Level}`]) {
          // 如果发现Level不存在于对象里,就说明这是新的level,那么就把这个新赋值到map里
          map[`${item.Level}`] = [item]
        } else {
          // 否则就说明,我已经创建过这个等级的值了,而且值为【item】那我就直接push进去
          map[`${item.Level}`]['push'](item)
        }
      })

      // 这里就拿到了一个根据Level为对象名字,值为数组装着相同Level的值的item的数组
      // {
      //   '2': [item1,item2],
      //   '3': [item4,item4]
      // }

      // 然后你可以做别的操作
      // 我这里给你转成数组对象的格式

      Object.keys(map).map(key => {
        // 这里的key就是 map的key ,2, 3那个  值就是对应的数组
        result.push({
          level: key,
          value: map[key],
          radio: 0
        })
      })
      // 现在的格式是[{level, value}]这种格式 继续加工处理
      result.reverse()
      // 把这个数组反转,按照level登记最大的在最前,遍历这个按照level等级生成的数组
      result.map((item, index) => {
        // 按照从最后往前的方式,这里第一个就是之前的最后一个,我们把最后一个里面的item,按照它自己的pid插入到之前一个等级的children里面成为它的子集
        const before = result[index + 1] // 因为我们是反着的数组所以是+1,否则应该是-1
        if (before) {
          item.value.map(currentValueItem => {
            before.value.map(beforeValueItem => {
              if (`${beforeValueItem.Id}` === `${currentValueItem.Pid}`) {
                if (Array.isArray(beforeValueItem.children)) {
                  beforeValueItem.children.push(currentValueItem)
                } else {
                  beforeValueItem.children = [currentValueItem]
                }
              }
            })
          })
        }
      })

      // 经过上面的处理,一层一层嵌套下去,最终的就只需要level是1的,其他的都不需要了
      // 就是说最后一个就是
      // [{
      //   level: 1,
      //   value: [{
      //     Level: 1,
      //     children: [{
      //       Level: 2,
      //       children: [] // 如果里面有3就会继续嵌套,没有子集就没有children
      //     }]
      //   }]
      // }]
      return result.slice(-1)
    },
  }
}

其他实现方式

其他实现方式:vue element 实现 多个单选、分类联动(2)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值