多选框 三级联动 vue (table 布局)

在这里插入图片描述

直接上代码

<template>
  <!-- 指定区域设置包邮条件 邮费-->
  <div class="area-set-freight">
    <el-dialog title="指定区域设置包邮条件" :visible.sync="areaVisible" width="896px" :before-close="cancelDialog">

      <!-- 指定区域设置运费 form -->
      <el-form ref="areaSetForm" :model="areaSetForm" :rules="areaSetFormRules">

        <el-row>
          <el-col :span="12">
            <el-form-item label="件数(件):" prop="count" label-width="80px">
              <el-input v-model="areaSetForm.count"></el-input>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="金额(CNY):" prop="price" label-width="110px">
              <el-input v-model="areaSetForm.price"></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="配送地区:" prop="count" label-width="80px" style="margin-top:10px">
          <el-input v-model="areaSetForm.address" disabled type="textarea" placeholder="请选择配送区域"></el-input>
        </el-form-item>

      </el-form>

      <!-- table 展示 -->
      <div class="area-set-freight__table__header">
        <div class="area-set-freight__table__header__item" style="width: 135px;padding-left:36px">地区</div>
        <div class="area-set-freight__table__header__item" style="width: 135px;padding-left:60px"></div>
        <div class="area-set-freight__table__header__item" style="width:100%;text-align: center;">
          <span style="color:#D70006;">*</span></div>
      </div>

      <div class="area-set-freight__table__content-box">
        <div v-for="(item, index) in tableData" :key="index" class="area-set-freight__table__content">
          <!-- 地区 第一级 -->
          <div class="area-set-freight__table__content__first">
            <el-checkbox
              v-model="item.check"
              :disabled="item.disable"
              style="margin-bottom:12px"
              :indeterminate="item.state"
              @change="firstChange($event, item)"
            >{
   
   { item.name }}</el-checkbox>
          </div>
          <!-- 省 第三级 -->
          <div class="area-set-freight__table__content__second">
            <div v-for="secondList in item.subQueryRegionList" :key="secondList.name" class="third-block">

              <div class="second-block">
                <el-checkbox
                  v-model="secondList.check"
                  :indeterminate="secondList.state"
                  :disabled="secondList.disable"
                  style="margin-bottom:12px;padding-left: 12px;"
                  @change="secondChange($event, secondList)"
                >{
   
   { secondList.name }}</el-checkbox>
              </div>

              <!-- 市 第二级 -->
              <div class="area-set-freight__table__content__third">
                <el-checkbox
                  v-for="thirdList in secondList.subQueryRegionList"
                  :key="thirdList.name"
                  v-model="thirdList.check"
                  style="margin-bottom:12px"
                  :disabled="thirdList.disable"
                  @change="thirdChange($event, thirdList)"
                >{
   
   { thirdList.name }}</el-checkbox>
              </div>

            </div>
          </div>

        </div>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelDialog">取 消</el-button>
        <el-button type="primary" @click="cancelDialog">保存</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
      
       getFreightRegion } from '@/api/freight-manage.js'

export default {
      
      
  name: 'AreaSetFreight',
  props: {
      
      
    areaVisible: {
      
      
      type: Boolean,
      default: false
    },
    // 判断是按件数还是重量 true 按件 false 重量
    isCount: {
      
      
      type: Boolean,
      default: false
    }
  },
  data() {
      
      
    // 首件数(件):支持输入1~9999的整数
    // 首重(kg):支持输入0.01至9999.99的数字
    var checkCount = (rule, value, callback) => {
      
      
      var reg = /^[0-9]+.?[0-9]*$/ // 验证是否是数字
      // 按件
      if (this.isCount && reg.test(value)) {
      
      
        if (parseFloat(value) > 0 && parseFloat(value) < 9999 && value.indexOf('.') === -1) {
      
      
          callback()
        } else {
      
      
          callback(new Error('支持输入1~9999的整数'))
        }
      // 按重
      } else {
      
      
        if (parseFloat(value) < 0 || parseFloat(value) > 9999.99) {
      
      
          callback(new Error('支持输入0.01至9999.99的数字'))
        } else {
      
      
          if (value.indexOf('.') && /^\d+(\.\d{1,2})?$/.test(value)) {
      
      
            callback()
          } else {
      
      
            callback(new Error('需要保留两位小数'))
          }
        }
      }
    }
    // 支持输入0.01至9999.99的数字
    var checkPrice = (rule, value, callback) => {
      
      
      // var reg = /^[0-9]+.?[0-9]*$/ // 验证是否是数字
      if (parseFloat(value) < 0 || parseFloat(value) > 9999.99) {
      
      
        callback(new Error('支持输入0.01至9999.99的数字'))
      } else {
      
      
        if (value.indexOf('.') && /^\d+(\.\d{1,2})?$/.test(value)) {
      
      
          callback()
        } else {
      
      
          callback(new Error('需要保留两位小数'))
        }
      }
    }
    return {
      
      
      // 币种 计费方式
      areaSetForm: {
      
      
        count: '', // 首件(件)
        price: '', // 首运费
        address: '' // 地区
      },
      // 运费模板 form 检验规则
      areaSetFormRules: {
      
      
        count: [{
      
       required: true, validator: checkCount, trigger: 'blur' }],
        price: [{
      
       required: true, validator: checkPrice, trigger: 'blur' }],
        address: [{
      
       required: true, message: '请输入', trigger: 'blur' }]
      },
      tableData: [],
      oldData: [] // 保存之前的数据
    }
  },
  created() {
      
      
    getFreightRegion().then(res => {
      
      
      // 增加三个字断 1.check 选中状态 2.disable 是否可以被选中 3.state 当前多选框状态
      const addAttr = {
      
       check: false, disable: false, state: false }
      for (const item of res.body) {
      
       // 一级
        Object.assign(item, addAttr)

        for (const secondItem of item.subQueryRegionList) {
      
       // 二级
          Object.assign(secondItem, addAttr)

          for (const thirdItem of secondItem.subQueryRegionList) {
      
       // 三级
            Object.assign(thirdItem, addAttr)
          }
        }
      }

      this.tableData = res.body
    })
  },
  methods: {
      
      
    cancelDialog() {
      
       // 关闭弹窗
      this.$emit('update:areaVisible', false)
    },
    firstChange(state, content) {
      
       // 1. 状态 2. 内容
      // 第一级变动 二级和三级 跟着变动
      for (const index in this.tableData) {
      
      
        if (content.name === this.tableData[index].name) {
      
      
          this.tableData[index].state = false // 取消 不确定状态

          for (const secondIndex in this.tableData[index].subQueryRegionList) {
      
      
            Object.assign(this.tableData[index].subQueryRegionList[secondIndex], {
      
       check: state, state: false })
            for (const thirdIndex in this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList) {
      
      
              Object.assign(this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList[thirdIndex], {
      
       check: state, state: false })
            }
          }
        }
      }
    },
    secondChange(state, content) {
      
      
      // 第三级改为全选
      // 1. 判断同类中是否都为 true 改变第一级的状态
      for (const index in this.tableData) {
      
      
        for (const secondIndex in this.tableData[index].subQueryRegionList) {
      
      
          if (this.tableData[index].subQueryRegionList[secondIndex].name === content.name) {
      
      
            this.tableData[index].subQueryRegionList[secondIndex].state = false // 取消 不确定状态

            // 1. 将第三级的全部改为相同的状态
            for (const thirdIndex in this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList) {
      
      
              Object.assign(this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList[thirdIndex], {
      
       check: state })
            }

            // 2. 如果是true 判断同级别中是否都为 true
            var secondFlag = true
            for (const flagIndex in this.tableData[index].subQueryRegionList) {
      
      
              if (this.tableData[index].subQueryRegionList[flagIndex].check === false) {
      
      
                secondFlag = false
              }
            }

            // 二级均为都为选中状态 改第一级为选中状态
            if (secondFlag) {
      
      
              Object.assign(this.tableData[index], {
      
       state: false, check: true })
            } else {
      
      
              // 判断二级中是否有 不确定状态 和 选中状态(改变一级的状态)
              var firstFlag = false
              for (const valueIndex in this.tableData[index].subQueryRegionList) {
      
      
                if (this.tableData[index].subQueryRegionList[valueIndex].check === true || // 选中
                  this.tableData[index].subQueryRegionList[valueIndex].state === true) {
      
       // 不确定状态
                  firstFlag = true
                }
              }
              if (firstFlag) {
      
       // true 有不确定状态 false 均没有选中
                Object.assign(this.tableData[index], {
      
       state: true, check: false })
              } else {
      
      
                Object.assign(this.tableData[index], {
      
       state: false, check: false })
              }
            }
          }
        }
      }
    },
    thirdChange(state, content) {
      
      
      // 1. 寻找到这个元素
      for (const index in this.tableData) {
      
      
        for (const secondIndex in this.tableData[index].subQueryRegionList) {
      
      
          for (const thirdIndex in this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList) {
      
      
            if (this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList[thirdIndex].name === content.name) {
      
      
              // 1. 判断同类是否都被选中
              var thirdFlag = true
              for (const threeIndex in this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList) {
      
      
                if (this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList[threeIndex].check === false) {
      
      
                  thirdFlag = false
                }
              }

              // 如果三级全部选中了 1. 修改二级的状态 2. 判断二级的状态 修改一级的状态
              if (thirdFlag) {
      
      
                Object.assign(this.tableData[index].subQueryRegionList[secondIndex], {
      
       state: false, check: true })

                // 判断二级是否均为 true 修改一级的状态
                var secondFlag = true
                for (const flagIndex in this.tableData[index].subQueryRegionList) {
      
      
                  if (this.tableData[index].subQueryRegionList[flagIndex].check === false) {
      
      
                    secondFlag = false
                  }
                }
                if (secondFlag) {
      
       // 全部都被选中了
                  Object.assign(this.tableData[index], {
      
       state: false, check: true })
                } else {
      
      
                  var secondFlag2 = false
                  for (const flagIndex in this.tableData[index].subQueryRegionList) {
      
      
                    if (this.tableData[index].subQueryRegionList[flagIndex].check === true) {
      
      
                      secondFlag2 = true
                    }
                  }
                  if (secondFlag2) {
      
       // 个别被选中
                    Object.assign(this.tableData[index], {
      
       state: true, check: false })
                  } else {
      
       // 没有一个被选中
                    Object.assign(this.tableData[index], {
      
       state: false, check: false })
                  }
                }
              } else {
      
       // 三级 同类中存在 没有被选中的
                var secondFlag3 = true // 判断是否都为 false
                for (const flagIndex in this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList) {
      
      
                  if (this.tableData[index].subQueryRegionList[secondIndex].subQueryRegionList[flagIndex].check === true) {
      
      
                    secondFlag3 = false
                  }
                }
                // 三级全部为 false
                if (secondFlag3) {
      
      
                  // 修改二级的状态
                  Object.assign(this.tableData[index].subQueryRegionList[secondIndex], {
      
       state: false, check: false })

                  var secondFlag22 = false
                  for (const flagIndex2 in this.tableData[index].subQueryRegionList) {
      
      
                    if (this.tableData[index].subQueryRegionList[flagIndex2].check === true ||
                    this.tableData[index].subQueryRegionList[flagIndex2].state === true
                    ) {
      
       secondFlag22 = true }
                  }
                  if (secondFlag22) {
      
       // 二级中有个别被选中
                    Object.assign(this.tableData[index], {
      
       state: true, check: false })
                  } else {
      
       // 二级中 无 选中
                    Object.assign(this.tableData[index], {
      
       state: false, check: false })
                  }
                } else {
      
       // 个别被选中
                  Object.assign(this.tableData[index], {
      
       state: true, check: false })
                  Object.assign(this.tableData[index].subQueryRegionList[secondIndex], {
      
       state: true, check: false })
                }
              }
            }
          }
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.area-set-freight {
      
      
  // 改变不可以输入的背景颜色
  /deep/.el-textarea.is-disabled .el-textarea__inner {
      
      
    background-color: #FFFFFF;
  }

  &__table__header {
      
      
    display: flex;
    font-size: 12px;
    font-family: MicrosoftYaHei;
    color: #303133;
    line-height: 16px;
    font-weight: bold;
    background: #F4F6F9;
    border: 1px solid #E5E7EE;
    height: 50px;
    line-height: 50px;
  }

  &__table__content {
      
      
    display: flex;
    justify-content: flex-start;
  }

  &__table__content__first {
      
      
    flex: 0 0 136px;
    border-left: #E5E7EE 1px solid;
    border-bottom: #E5E7EE 1px solid;
    padding-top: 12px;
    padding-bottom: 5px;
    padding-left: 14px;
  }

  &__table__content__second {
      
      
    flex: 0 0 136px;
    // border-top: #E5E7EE 1px solid;
    border-left: #E5E7EE 1px solid;
  }

  &__table__content__third {
      
      
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    width: 536px;
    border-bottom: #E5E7EE 1px solid;
    border-left: #E5E7EE 1px solid;
    border-right: #E5E7EE 1px solid;
    padding-top: 12px;
    padding-bottom: 5px;
    padding-left: 14px;
  }

  &__table__content-box {
      
      
    height: 390px;
    overflow: scroll;
    overflow-x: hidden;
    border-bottom: #E5E7EE 1px solid;
  }
}

// 修改 input label 字体样式
/deep/.el-form-item__label {
      
      
  font-size: 12px;
  font-weight: bold;
  font-size: 12px;
  font-family: MicrosoftYaHei;
  color: #303133;
}

.second-block {
      
      
  width: 136px;
  padding-top: 10px;
  border-bottom: #E5E7EE 1px solid;
}

.third-block {
      
      
  display: flex;
  justify-content: flex-start;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_40639095/article/details/121336222
今日推荐