双重表格,跨页表格选中,表格内写入选中框

在这里插入图片描述实现效果如上,表格内需要有checkbox,跨页记录状态,纯手写
组件内:

<template>
  <div class="transDoubleTable">
    <div class="content-data">
      <div class="content-table">
        <div class="row-ever" v-for="(item, index) in transTableOne" :key="'row1' + index">
          <div :class="'column-ever column-ever'+childIndex" v-for="(childItem, childIndex) in item"
            :key="'child1' + childIndex" :style="'width:calc((100% - 40px)/' + (item.length - 1) +')'">
            <a-checkbox v-model="childItem.checkValue" v-if="childItem.hasCheckBox"
              @change="changeValueOne(index,childIndex,childItem)" :indeterminate='childItem.indeterminate'></a-checkbox>
            <span
              :class="'content-title ' + (childItem.hasCheckBox === true && index !== 0 ? 'changeTitle' : '')">{{childItem.title}}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="content-data">
      <div class="content-table">
        <div class="row-ever" v-for="(item, index) in transTableTwo" :key="'row2' + index">
          <div :class="'column-ever column-ever'+childIndex" v-for="(childItem, childIndex) in item"
            :key="'child2' + childIndex" :style="'width:calc((100% - 40px)/' + (item.length - 1) +')'">
            <a-checkbox v-model="childItem.checkValue" v-if="childItem.hasCheckBox"
              @change="changeValueTwo(index,childIndex,childItem)" :indeterminate='childItem.indeterminate'></a-checkbox>
            <span
              :class="'content-title ' + (childItem.hasCheckBox === true && index !== 0 ? 'changeTitle' : '')">{{childItem.title}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    name: 'transDoubleTable',
    data() {
      return {
        transTableOne: [],
        transTableTwo: [],
        leftDisabled: false
      }
    },
    props: {
      // 选中数据列表
      choosedDataList: {
        type: Array,
        default:() => {
          return []
        }
      },
      // 源数据列表
      sourceList: {
        type: Array,
        default:() => {
          return []
        }
      },
      // 目标数据列表
      targetList: {
        type: Array,
        default:() => {
          return []
        }
      },
    },
    watch: {
      sourceList: {
        handler(val) {
          this.transTableOne = []
          for (let i=0;i<=val.length;i++) {
            this.transTableOne.push([])
            this.transTableOne[i][0] = {
              hasCheckBox: false,
              title: '',
              checkValue: false,
              indeterminate: false
            }
            if (i === 0) {
              for (let j in this.sourceList[i]) {
                this.transTableOne[i].push({
                  hasCheckBox: false,
                  title: j,
                  checkValue: false,
                  indeterminate: false
                })
              }
            } else {
              for (let j in this.sourceList[i - 1]) {
                this.transTableOne[i].push({
                  hasCheckBox: false,
                  title: this.sourceList[i - 1][j],
                  checkValue: false,
                  indeterminate: false
                })
              }
            }
          }
          // this.compareDifference()
          // this.initDataCheckBox()
          // this.initChoosedTable()
        },
        deep: true,
        immediate: true
      },
      targetList: {
        handler(val) {
          this.transTableTwo = []
          for (let i=0;i<=val.length;i++) {
            this.transTableTwo.push([])
            this.transTableTwo[i][0] = {
              hasCheckBox: false,
              title: '',
              checkValue: false,
              indeterminate: false
            }
            if (i === 0) {
              for (let j in this.targetList[i]) {
                this.transTableTwo[i].push({
                  hasCheckBox: false,
                  title: j,
                  checkValue: false,
                  indeterminate: false
                })
              }
            } else {
              for (let j in this.targetList[i - 1]) {
                this.transTableTwo[i].push({
                  hasCheckBox: false,
                  title: this.targetList[i - 1][j],
                  checkValue: false,
                  indeterminate: false
                })
              }
            }
          }
          this.compareDifference()
          this.initDataCheckBox()
          this.initChoosedTable()
        },
        deep: true,
        immediate: true
      },
    },
    mounted() {
    },
    methods: {
      /**
       * @desc: 对比两个表格差异
       * @return {*}
       */
      compareDifference () {
        for (let i=0;i<this.transTableOne.length;i++) {
          for (let j=0;j<this.transTableOne[i].length;j++) {
            if (this.transTableOne[i][j].title !== this.transTableTwo[i][j].title) {
              this.transTableOne[i][j].hasCheckBox = true
              this.transTableTwo[i][j].hasCheckBox = true
            }
          }
        }
      },
      /**
       * @desc: 初始化全表内选择框
       * @return {*}
       */
      initDataCheckBox () {
        let totalHasCheck = false
        for (let i=1;i<this.transTableOne.length;i++) {
          for (let j=1;j<this.transTableOne[i].length;j++) {
            if (this.transTableOne[i][j].hasCheckBox === true) {
              this.transTableOne[i][0].hasCheckBox = true
              this.transTableOne[0][j].hasCheckBox = true
              this.transTableTwo[i][0].hasCheckBox = true
              this.transTableTwo[0][j].hasCheckBox = true
              totalHasCheck = true
            }
          }
        }
        if (totalHasCheck) {
          this.transTableOne[0][0].hasCheckBox = true
          this.transTableTwo[0][0].hasCheckBox = true
        }
      },
      /**
       * @desc: 渲染选中内容
       * @return {*}
       */
      initChoosedTable () {
        let nowSourceTitleList = this.choosedDataList.map(item => {
          return item.sourceTitle
        })
        for (let i=0;i<this.transTableOne.length;i++) {
          for (let j=0;j<this.transTableOne[i].length;j++) {
            if (nowSourceTitleList.includes(this.transTableOne[i][j].title)) {
              this.transTableOne[i][j].checkValue = true
              this.transTableTwo[i][j].checkValue = true
            }
          }
        }
        this.playUpTableHead()
      },
      /**
       * @desc: 渲染表头和首列的变化
       * @return {*}
       */
      playUpTableHead () {
        // 第一行表头状态
        let rowTrueList = new Array(this.transTableOne[0].length).fill(true)
        // 第一列表头状态
        let columnTrueList = new Array(this.transTableOne.length).fill(true)
        
        for (let i = 1; i < this.transTableOne.length; i++) {
          let totalJudgeList = this.transTableOne[i].filter((item, index) => {
            return item.hasCheckBox === true && index > 0
          })
          let falseList = this.transTableOne[i].filter((item, index) => {
            return item.checkValue !== true && item.hasCheckBox === true && index > 0
          })
          if (falseList.length === 0) {
            columnTrueList[i] = true
          } else if (falseList.length > 0 && falseList.length < totalJudgeList.length) {
            columnTrueList[i] = 'indeterminate'
          } else{
            columnTrueList[i] = false
          }
        }
        for (let j = 1; j < this.transTableOne[0].length; j++) {
          let falseLength = 0
          let totalJudgeLength = 0
          for (let i = 1;i < this.transTableOne.length;i++) {
            if (this.transTableOne[i][j].hasCheckBox === true) {
              totalJudgeLength = totalJudgeLength + 1
              if (this.transTableOne[i][j].checkValue !== true) {
                falseLength = falseLength + 1
              }
            }
          }
          if (falseLength === 0) {
            rowTrueList[j] = true
          } else if (falseLength > 0 && falseLength < totalJudgeLength) {
            rowTrueList[j] = 'indeterminate'
          } else{
            rowTrueList[j] = false
          }
        }
        
        for (let i = 1; i < this.transTableOne[0].length; i++) {
          if (rowTrueList[i] === 'indeterminate') {
            this.transTableOne[0][i].indeterminate = true
            this.transTableOne[0][i].checkValue = false
          } else {
            this.transTableOne[0][i].checkValue = rowTrueList[i]
            this.transTableOne[0][i].indeterminate = false
          }
        }
        for (let i = 1; i < this.transTableOne.length; i++) {
          if (columnTrueList[i] === 'indeterminate') {
            this.transTableOne[i][0].indeterminate = true
            this.transTableOne[i][0].checkValue = false
          } else {
            this.transTableOne[i][0].checkValue = columnTrueList[i]
            this.transTableOne[i][0].indeterminate = false
          }
        }
        // 判断是否会造成全选变化
        for (let i=0;i<this.transTableOne.length;i++) {
          for (let j=0;j<this.transTableOne[i].length;j++) {
            if ((i === 0 || j === 0) && this.transTableOne[i][j].hasCheckBox === false) {
              if (i === 0) {
                rowTrueList[j] = 'hasCheckBoxFalse'
              }
              if (j === 0) {
                columnTrueList[i] = 'hasCheckBoxFalse'
              }
            }
          }
        }
        let newList = rowTrueList.concat(columnTrueList)
        newList.splice(0,1)
        newList.splice(rowTrueList.length - 1,1)
        if (!newList.includes(false) && !newList.includes('indeterminate')) {
          this.transTableOne[0][0].checkValue = true
          this.transTableOne[0][0].indeterminate = false
        } else if (!newList.includes(true) && !newList.includes('indeterminate')) {
          this.transTableOne[0][0].checkValue = false
          this.transTableOne[0][0].indeterminate = false
        } else {
          this.transTableOne[0][0].checkValue = false
          this.transTableOne[0][0].indeterminate = true
        }
        
        // 对第二个表格赋值
        for (let i=0;i<this.transTableOne.length;i++) {
          for (let j=0;j<this.transTableOne[i].length;j++) {
            this.transTableTwo[i][j].checkValue = this.transTableOne[i][j].checkValue
            this.transTableTwo[i][j].indeterminate = this.transTableOne[i][j].indeterminate
          }
        }
      },
      /**
       * @desc: 左边表格点击变化
       * @return {*}
       */
      changeValueOne(rowIndex, columnIndex, item) {
        let changeList = []
        // 勾选左上角全选变化
        if (rowIndex === 0 && columnIndex === 0) {
          for (let i = 0; i < this.transTableOne.length; i++) {
            for (let j = 0; j < this.transTableOne[j].length; j++) {
              this.transTableOne[i][j].checkValue = item.checkValue
              if (i !== 0 && j !== 0 && this.transTableOne[i][j].hasCheckBox) {
                changeList.push({
                  sourceTitle: this.transTableOne[i][j].title,
                  targetTitle: this.transTableTwo[i][j].title
                })
              }
            }
          }
        }
        // 勾选第一行表头变化
        if (rowIndex === 0 && columnIndex !== 0) {
          for (let i = 0; i < this.transTableOne.length; i++) {
            for (let j = 0; j < this.transTableOne[j].length; j++) {
              if (j === columnIndex) {
                this.transTableOne[i][columnIndex].checkValue = item.checkValue
                if (i !== 0 && this.transTableOne[i][columnIndex].hasCheckBox) {
                  changeList.push({
                    sourceTitle: this.transTableOne[i][j].title,
                    targetTitle: this.transTableTwo[i][j].title
                  })
                }
              }
            }
          }
        }
        // 勾选第一列表头变化
        if (rowIndex !== 0 && columnIndex === 0) {
          for (let i = 0; i < this.transTableOne.length; i++) {
            for (let j = 0; j < this.transTableOne[j].length; j++) {
              if (i === rowIndex) {
                this.transTableOne[rowIndex][j].checkValue = item.checkValue
                if (j !== 0 && this.transTableOne[rowIndex][j].hasCheckBox) {
                  changeList.push({
                    sourceTitle: this.transTableOne[i][j].title,
                    targetTitle: this.transTableTwo[i][j].title
                  })
                }
              }
            }
          }
        }
        if (rowIndex !== 0 && columnIndex !== 0) {
          changeList.push({
            sourceTitle: this.transTableOne[rowIndex][columnIndex].title,
            targetTitle: this.transTableTwo[rowIndex][columnIndex].title
          })
        }
        this.$emit('changeChoosedData', changeList, item.checkValue)
        this.playUpTableHead()
      },
      /**
       * @desc: 右边表格点击变化
       * @return {*}
       */
      changeValueTwo(rowIndex, columnIndex, item) {
        let changeList = []
        // 勾选左上角全选变化
        if (rowIndex === 0 && columnIndex === 0) {
          for (let i = 0; i < this.transTableTwo.length; i++) {
            for (let j = 0; j < this.transTableTwo[j].length; j++) {
              this.transTableTwo[i][j].checkValue = item.checkValue
              if (i !== 0 && j !== 0 && this.transTableTwo[i][j].hasCheckBox) {
                changeList.push({
                  sourceTitle: this.transTableOne[i][j].title,
                  targetTitle: this.transTableTwo[i][j].title
                })
              }
            }
          }
        }
        // 勾选第一行表头变化
        if (rowIndex === 0 && columnIndex !== 0) {
          for (let i = 0; i < this.transTableTwo.length; i++) {
            for (let j = 0; j < this.transTableTwo[j].length; j++) {
              if (j === columnIndex) {
                this.transTableTwo[i][columnIndex].checkValue = item.checkValue
                if (i !== 0 && this.transTableTwo[i][columnIndex].hasCheckBox) {
                  changeList.push({
                    sourceTitle: this.transTableOne[i][j].title,
                    targetTitle: this.transTableTwo[i][j].title
                  })
                }
              }
            }
          }
        }
        // 勾选第一列表头变化
        if (rowIndex !== 0 && columnIndex === 0) {
          for (let i = 0; i < this.transTableTwo.length; i++) {
            for (let j = 0; j < this.transTableTwo[j].length; j++) {
              if (i === rowIndex) {
                this.transTableTwo[rowIndex][j].checkValue = item.checkValue
                if (j !== 0 && this.transTableTwo[rowIndex][j].hasCheckBox) {
                  changeList.push({
                    sourceTitle: this.transTableOne[i][j].title,
                    targetTitle: this.transTableTwo[i][j].title
                  })
                }
              }
            }
          }
        }
        if (rowIndex !== 0 && columnIndex !== 0) {
          changeList.push({
            sourceTitle: this.transTableOne[rowIndex][columnIndex].title,
            targetTitle: this.transTableTwo[rowIndex][columnIndex].title
          })
        }
        this.$emit('changeChoosedData', changeList, item.checkValue)
        // 第一行表头状态
        let rowTrueList = new Array(this.transTableTwo[0].length).fill(true)
        // 第一列表头状态
        let columnTrueList = new Array(this.transTableTwo.length).fill(true)
        
        for (let i = 1; i < this.transTableTwo.length; i++) {
          let totalJudgeList = this.transTableTwo[i].filter((item, index) => {
            return item.hasCheckBox === true && index > 0
          })
          let falseList = this.transTableTwo[i].filter((item, index) => {
            return item.checkValue !== true && item.hasCheckBox === true && index > 0
          })
          if (falseList.length === 0) {
            columnTrueList[i] = true
          } else if (falseList.length > 0 && falseList.length < totalJudgeList.length) {
            columnTrueList[i] = 'indeterminate'
          } else{
            columnTrueList[i] = false
          }
        }
        for (let j = 1; j < this.transTableTwo[0].length; j++) {
          let falseLength = 0
          let totalJudgeLength = 0
          for (let i = 1;i < this.transTableTwo.length;i++) {
            if (this.transTableTwo[i][j].hasCheckBox === true) {
              totalJudgeLength = totalJudgeLength + 1
              if (this.transTableTwo[i][j].checkValue !== true) {
                falseLength = falseLength + 1
              }
            }
          }
          if (falseLength === 0) {
            rowTrueList[j] = true
          } else if (falseLength > 0 && falseLength < totalJudgeLength) {
            rowTrueList[j] = 'indeterminate'
          } else{
            rowTrueList[j] = false
          }
        }
        
        for (let i = 1; i < this.transTableTwo[0].length; i++) {
          if (rowTrueList[i] === 'indeterminate') {
            this.transTableTwo[0][i].indeterminate = true
            this.transTableTwo[0][i].checkValue = false
          } else {
            this.transTableTwo[0][i].checkValue = rowTrueList[i]
            this.transTableTwo[0][i].indeterminate = false
          }
        }
        for (let i = 1; i < this.transTableTwo.length; i++) {
          if (columnTrueList[i] === 'indeterminate') {
            this.transTableTwo[i][0].indeterminate = true
            this.transTableTwo[i][0].checkValue = false
          } else {
            this.transTableTwo[i][0].checkValue = columnTrueList[i]
            this.transTableTwo[i][0].indeterminate = false
          }
        }
        
        // 判断是否会造成全选变化
        for (let i=0;i<this.transTableTwo.length;i++) {
          for (let j=0;j<this.transTableTwo[i].length;j++) {
            if ((i === 0 || j === 0) && this.transTableTwo[i][j].hasCheckBox === false) {
              if (i === 0) {
                rowTrueList[j] = 'hasCheckBoxFalse'
              }
              if (j === 0) {
                columnTrueList[i] = 'hasCheckBoxFalse'
              }
            }
          }
        }
        let newList = rowTrueList.concat(columnTrueList)
        
        newList.splice(0,1)
        newList.splice(rowTrueList.length - 1,1)
        if (!newList.includes(false) && !newList.includes('indeterminate')) {
          this.transTableTwo[0][0].checkValue = true
          this.transTableTwo[0][0].indeterminate = false
        } else if (!newList.includes(true) && !newList.includes('indeterminate')) {
          this.transTableTwo[0][0].checkValue = false
          this.transTableTwo[0][0].indeterminate = false
        } else {
          this.transTableTwo[0][0].checkValue = false
          this.transTableTwo[0][0].indeterminate = true
        }
        
        // 对第二个表格赋值
        for (let i=0;i<this.transTableTwo.length;i++) {
          for (let j=0;j<this.transTableTwo[i].length;j++) {
            this.transTableOne[i][j].checkValue = this.transTableTwo[i][j].checkValue
            this.transTableOne[i][j].indeterminate = this.transTableTwo[i][j].indeterminate
          }
        }
      }
    }
  }
</script>

样式(基本样式,需要调整):

  .transDir {
    display: flex;
    flex-direction: column;
    justify-content: center;
    ::v-deep .ant-btn-primary{
      width: 120px;
      text-align: center;
      margin-top: 10px;
    }
  }
  .column-ever {
    text-align: center;
    height: 40px;
    line-height: 40px;
    border-right: 1px solid #EFF2FB;
    border-bottom: 1px solid #EFF2FB;
    position: relative;
  }

  .changeTitle {
    color: #D9001B !important;
  }

  .column-ever0 {
    width: 40px !important;

    ::v-deep .ant-checkbox-wrapper {
      position: relative !important;
      left: 0px !important;
    }
  }

  .transDoubleTable {
    display: flex;
    .content-data:last-of-type {
      margin-right: 0px;
    }
    

    .content-data {
      width: calc(50% - 10px);
      margin-right: 20px;
      border-left: 1px solid #E3E6EF;
      border-bottom: 1px solid #E3E6EF;
      border-right: 1px solid #E3E6EF;
      .content-table{
        margin: 23.64px 36px 0px 15px;
        border-left: 1px solid #EFF2FB;
        border-top: 1px solid #EFF2FB;
        &:first-child{
          background: #F5F6FA !important;
          border-radius: 3px 3px 0px 0px;
        }
      }
      
      .row-ever {
        display: flex;

        .content-title {
          width: 80%;
          margin-left: 10%;
          text-align: center;
          display: inline-block;
        }

        ::v-deep .ant-checkbox-wrapper {
          position: absolute;
          left: 5px;
        }
      }
      
    }
  }

使用:


<template>
  <div class="compare-detail">
    <TransDoubleTable :choosedDataList='choosedDataList' :sourceList='sourceList' :targetList='targetList' @changeChoosedData='changeChoosedData'></TransDoubleTable>
        <a-pagination :current="page.current" show-quick-jumper :showSizeChanger='page.showSizeChanger' :size='page.size' :total="page.total" :showTotal='page.showTotal' :pageSize='page.pageSize' :pageSizeOptions='page.pageSizeOptions' @change="onChangePage" @showSizeChange="onChangeSizePage"/>
  </div>
</template>

<script>
  import TransDoubleTable from '@/components/transDoubleTable/index'
  export default {
    name: 'compareDetail',
    components: {
      TransDoubleTable
    },
    data() {
      return {
        page: {
          total: 50,
          current: 1,
          pageSize: 10,
          pageSizeOptions: ['10', '20', '50'],
          showTotal: (total) => {
            return ' 共 ' + total + ' 项数据'
          },
          showSizeChanger: true,
          size: 'middle'
        },
        // 已选中的单个数据列表
        choosedDataList: [],
        // 源数据列表
        sourceList: [],
        // 目标数据列表
        targetList: []
      }
    },
    watch: {
    },
    created() {
      this.initTransTableData(this.page.current, this.page.pageSize)
    },
    methods: {
      /**
       * @desc: 切换页码
       * @return {*}
       */
      onChangePage(current, pageSize){
        this.initTransTableData(current, pageSize)
        this.page.current = current
      },
      /**
       * @desc: 页面数量大小变化
       * @return {*}
       */
      onChangeSizePage(current, pageSize){
        this.initTransTableData(current, pageSize)
        this.page.pageSize = pageSize
      },
      /**
       * @desc: 获取对应页码和内容的源表数据和目标表数据
       * @return {*}
       */
      initTransTableData(current, pageSize){
        let sourceList = []
        for (let i = 0; i < pageSize; i++) {
          sourceList.push({})
          for (let j=0; j < 4; j++) {
            sourceList[i]['column' + '-' + current + '-' + i + '-' + j] = 'content' + current + '-' + i + '-' + j
          }
        }
        
        let targetList = []
        for (let i = 0; i < pageSize; i++) {
          targetList.push({})
          for (let j=0; j < 4; j++) {
            let nowStatsu = j > 1
            targetList[i]['column' + '-' + current + '-' + i + '-' + j] = nowStatsu ? 'content' + current + '-' + i + '-' + j + 'C' : 'content' + current + '-' + i + '-' + j
          }
        }
        this.sourceList = sourceList
        this.targetList = targetList
      },
      /**
       * @desc: 表格内选中数据变化
       * @return {*}
       */
      changeChoosedData (titleList, status) {
        // status为true时,向选中数组内添加内容,为false,删除对应内容
        if (status) {
          // 合并列表
          let totalList = this.choosedDataList.concat(titleList)
          // 去除重复后新列表
          let newList = []
          totalList.map(item => {
            let newListSourceTitleList = newList.map(item => {
              return item.sourceTitle
            })
            if (!newListSourceTitleList.includes(item.sourceTitle)) {
              newList.push(item)
            }
          })
          this.choosedDataList = newList
        } else {
          let nowSourceTitleList = titleList.map(item => {
            return item.sourceTitle
          })
          this.choosedDataList = this.choosedDataList.filter(item => {
            if (!nowSourceTitleList.includes(item.sourceTitle)) {
              return item
            }
          })
        }
      }
    }
  }
  
</script>

小小记录一手,写了差不多四个小时,龟龟~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值