vue+ts 实现复杂级联选择

一:问题描述:

用户购买课程,

预期效果:

vue+ts 实现复杂级联选择_第1张图片vue+ts 实现复杂级联选择_第2张图片

二.级联选择器的需求

1.vue+ ts 实现可复用组件

2.已经购买的课程显示disabled且只读

3.点击每级的checkbox实现子级的全选与取消全选

4.点击每个tab显示子级的所有课程且添加背景

5.子级未全选父级显示选一半状态

三 .组件设计

输入: isEditCourse控制级联选择的弹框显示,navTitles 为级联选择器的nav数组 ,searchCourseDataTo存储级联选择器的数据数组。类型为:

interface ISearchData {
  objectId: string;
  firstStage: string;//第一级
  secondStage: string;//第二级
  thirdStage: string;//第三级
  isSelected: boolean;//控制checkbox
  isDisabled: boolean;//是否只读
}

组件的使用

实现思路:当组件调用时触发getFirstArr()获取第一级的数据,注意:需要去重且当一种类型下有多个课时且有一个为只读时当前的tab的isOneSelect && isSelected属性应为true(即状态为显示一半),当子集全为只读时 !isOneSelect && isSelected属性应为true, 获取第二级思路与第一级相同、

四.实现

用户点击checkbox按钮时,分三种情况,

1.子级无只读项 :这种情况是最简单的一种,只需将所有的firstStage 等于当前 firstStage 的isSelected 取 当前值

2.子集有只读项: 当子集含有只读项时,用户每次点击checkbox时 修改的是 isOneSelected(控制按钮的状态为显示一半) 项

3.子集全为只读项: 当子集全为只读时用户点击checkBox禁止修改按钮的状态,即不做任何改变

注意: 当用户点击第二级时,第一级需要根据子集是否全选改变上一级的按钮状态。这也是这个组件逻辑的难点之一,

所有的父级按钮的状态(是否为选中一半状态)都需要响应子级的变化。

核心代码

1.当组件调用时触发getFirstArr()获取第一级的数据,

private getFirstStage() {
    var _firstStage: string[] = []
    this.firstStageArr = []
    this.classDataAll.forEach(element => {
      if (!_firstStage.includes(element.firstStage)) {
        _firstStage.push(element.firstStage)
        this.firstStageArr.push({
          isSelected: element.isSelected,
          firstStage: element.firstStage,
          isOneSelected: false
        })
      } else if (element.isBuy) {
        // 如果一个课程类型下有多个课时且用户已经有某课时的权限时,课程类型为选中状态
        this.firstStageArr = this.firstStageArr.map(e => {
          if (e.firstStage === element.firstStage) {
            e.isSelected = element.isBuy
          }
          return e
        })
      }
    })
    // 判断第一级的下级是否全选
    this.getSelectAllFirstStageNext()
  }

2.点击checkbox 事件

private selectFirstStages(index: number) {
    this.secondStageArr = []
    this.thirdStageArr = []
    this.isSelectedFirstStage = index
    var _isSelected = false
    var _isBuy = false
    _isSelected = (this.firstStageArr[index].isSelected && this.firstStageArr[index].isOneSelected) ? true : !this.firstStageArr[index].isSelected
    // 类型下是否有已购买的课程
    _isBuy =this.classDataAll.some(e => e.isBuy && e.firstStage === this.firstStageArr[index].firstStage)
    this.classDataAll.forEach(e => {
      if (e.firstStage === this.firstStageArr[index].firstStage) {
        if (this.firstStageArr[index].isOneSelected) {
          e.isSelected = _isSelected
          this.firstStageArr[index].isSelected = true
          this.firstStageArr[index].isOneSelected = false
        } else {
          e.isSelected = e.isBuy ? e.isBuy : _isSelected
          this.firstStageArr[index].isSelected = _isSelected
        }
      }
    })
    // 取消全选时如果子列有已购买的课程则按钮的状态为选择一半
    if (!this.firstStageArr[index].isSelected && !this.firstStageArr[index].isOneSelected && _isBuy) {
      this.firstStageArr[index].isOneSelected = true
    }
    this.getSecondStage(this.firstStageArr[index].firstStage)//获取子级
    this.isUserSelectedSum()//获取已选择项的总和
    this.isFirstDisabled()// 当子级全为disabled状态时,父级禁止切换状态
  }

 

 

你可能感兴趣的:(vue+ts 实现复杂级联选择)