vxe-table实现表格双选联动

初版比较简陋,也没找到合适的插件,如在阅读过程中发现有的插件可以分享我一个,有错误的也希望给予指正。

1、先放两张成品图

在这里插入图片描述

在这里插入图片描述

2、部分代码说明
      watch中对两个复杂数组进行监听需要增加deep:true属性,打印newVal和oldVal发现两个值都一样,原因是因为他两个指向是一样的,所以需要
  通过计算属性computed来获取变化前后的值
      通过for...in...可以获取对象的键
      Array.from(new Set(tempArr)).toString()可以将简单数组先排序再转字符串
      数组不能通过===或者==判断是否相同,所以组要转一下在判断是否相同JSON.stringify(newVal) !== JSON.stringify(oldVal)
3、完整代码部分
<vxe-table
   :data="array"
   :loading="loading"
   row-id="id"
   size="small"
   ref="mandateTable"
   align="center"
   border
   auto-resize
   resizable
   show-header-overflow
   show-overflow
   highlight-hover-row
   class="table">
   <vxe-column field="name" title="应用访问权限" align="left" header-align="center">
       <template #default="scope">
           <vxe-checkbox v-model="scope.row.check" :indeterminate="scope.row.check === '2'" @change="checkChangeEvent(scope.$rowIndex, scope.$columnIndex, scope.row.check, scope.type)" checked-value="1" unchecked-value="0">{{scope.row.name}}</vxe-checkbox>
       </template>
   </vxe-column>
   <vxe-colgroup field="b" title="可用登录方式">
       <vxe-column v-for="(item, index) in arrayHeader" :key="'arrayHeader' + index" :title="item.name"  :field="item.field">
           <template #header="scope">
               <vxe-checkbox v-model="item.check" :indeterminate="item.check === '2'" @change="checkChangeEvent(scope.$rowIndex, scope.$columnIndex,item.check, scope.type, item.field)" checked-value="1" unchecked-value="0">{{item.name}}</vxe-checkbox>
           </template>
           <template #default="scope">
               <span v-if="scope.row[item.field] === '2'" style="color: #DDE0E7;">/</span>
               <vxe-checkbox v-else v-model="scope.row[item.field]" @change="checkChangeEvent(scope.$rowIndex, scope.$columnIndex, scope.row[item.field], scope.type, item.field, scope.row)" :disabled="scope.row[item.field] === '2'" checked-value="1" unchecked-value="0"></vxe-checkbox>
           </template>
       </vxe-column>
   </vxe-colgroup>
</vxe-table>
<script>
export default {
    name: 'mandate-form',
    data() {
        return {
            loading: false,
            arrayHeader: [
                { id: '11', name: '登录1', field: 'jobNum', check: '0'},
                { id: '12', name: '登录2', field: 'loginName', check: '0'},
                { id: '13', name: '登录3', field: 'IDcard', check: '0'},
                { id: '14', name: '登录4', field: 'phone', check: '0'},
                { id: '15', name: '登录5', field: 'captcha', check: '0'},
                { id: '16', name: '登录6', field: 'email', check: '0'},
                { id: '17', name: '登录7', field: 'certificate', check: '0'}
            ],
            array: [
                //check: 0 未选中  1选中  2半选中   其他: 0 未选中   1选中  2未选且禁止
                { id: 10001, name: '平台端', jobNum: '0', loginName: '2', IDcard: '0', phone: '0', captcha: '0', email: '0', certificate: '2', check: '0' },
                { id: 10002, name: 'APP', jobNum: '0', loginName: '2', IDcard: '2', phone: '2', captcha: '2', email: '0', certificate: '2', check: '0' },
                { id: 10003, name: 'XX系统', jobNum: '0', loginName: '2', IDcard: '0', phone: '0', captcha: '0', email: '2', certificate: '0', check: '0' },
                { id: 10004, name: 'XX APP', jobNum: '0', loginName: '0', IDcard: '0', phone: '0', captcha: '0', email: '0', certificate: '0', check: '0' },
            ]
        }
    },
    computed: {
        newArrayHeader() {
            return JSON.parse(JSON.stringify(this.arrayHeader))
        },
        newArray() {
            return JSON.parse(JSON.stringify(this.array))
        }
    },
    watch:{
        'newArrayHeader':{
            handler: function (newVal, oldVal) {
                //顶栏联动左栏全选
                if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
                    this.arrayHeader.forEach(h_item => {
                        this.array.forEach(item => {
                            if (item[h_item.field] !== '2') {
                                let tempArr = []
                                for (let key in item) {
                                    if (key !== 'name' && key !== 'id') {
                                        tempArr.push(item[key])
                                    }
                                }
                                let tempStr = Array.from(new Set(tempArr)).toString()
                                if (tempStr === '0,2' || tempStr === '2,0' || tempStr === '0') {
                                    item.check = '0'
                                } else if(tempStr === '1,2' || tempStr === '2,1' || tempStr === '1') {
                                    item.check = '1'
                                } else {
                                    item.check = '2'
                                }
                            }
                        })
                    })
                }
            },
            deep:true
        },
        'newArray':{
            handler: function (newVal, oldVal) {
                //左栏联动顶栏全选
                if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
                    this.arrayHeader.forEach((h_item, index) => {
                        let tempArr = []
                        this.array.forEach(item => {
                            for(let key in item) {
                                if (key !== 'name' && key !== 'id') {
                                    tempArr.push(item[h_item.field])
                                }
                            }
                        })
                        let tempStr = Array.from(new Set(tempArr)).toString()
                        if (tempStr === '1,2' || tempStr === '2,1' || tempStr === '1') {
                            this.arrayHeader[index].check = '1'
                        } else if (tempStr === '0,2' || tempStr === '2,0' || tempStr === '0') {
                            this.arrayHeader[index].check = '0'
                        } else {
                            this.arrayHeader[index].check = '2'
                        }
                    })
                }
            },
            deep:true
        }
    },
    methods: {
        checkChangeEvent(row, col, value, type, field, rowData) {
            /*
            * value 表示点击项的值
            * type 等于header为表头   等于body为主体
            * field 表格右侧表头  用以区分列
            * rowData 当前行的所有数据
            * 当col为0  表示后面除过禁选项需要全选  不为0时需要判断除过禁选项是否都被选择从而决定前面是不是为1
            * */
            if (type === 'body' && col === 0) {
                //表格左栏全选
                for(let key in this.array[col]) {
                    if (key !== 'name' && key !== 'id' && (value === '1' || value === '2')) {
                        this.array[row][key] = this.array[row][key] === '2' ? '2' : '1'
                    } else if (key !== 'name' && key !== 'id' && value === '0') {
                        this.array[row][key] =  this.array[row][key] === '2' ? '2' : '0'
                    }
                }
            } else if (type === 'header' && row === 1) {
                //表格顶栏全选
                this.array.forEach(item => {
                    if ((value === '1' || value === '2') && item[field] !== '2') {
                        this.$set(item, field, '1')

                    } else if (value === '0' && item[field] !== '2') {
                        this.$set(item, field, '0')
                    }
                })
            } else {
                //表格中选择
                let tempHead = []
                this.array.forEach((item) => {
                    if (rowData.id === item.id) {
                        let tempArr = []
                        for(let i in item) {
                            if (i !== 'check' && i !== 'id' && i !== 'name') {
                                tempArr.push(item[i])
                            }
                        }
                        let finallyArr = Array.from(new Set(tempArr))
                        if (finallyArr.toString() === '0,2' || finallyArr.toString() === '0') {
                            item.check = '0'
                        } else if (finallyArr.toString() === '1,2' || finallyArr.toString() === '1') {
                            item.check = '1'
                        } else {
                            item.check = '2'
                        }

                    }
                    tempHead.push(item[field])

                })
                let finallyHead = Array.from(new Set(tempHead))
                this.arrayHeader.forEach((head) => {
                    if (head.field === field) {
                        if (finallyHead.toString() === '0,2' || finallyHead.toString() === '0' || finallyHead.toString() === '2,0') {
                            head.check = '0'
                        } else if (finallyHead.toString() === '1,2' || finallyHead.toString() === '1' || finallyHead.toString() === '2,1') {
                            head.check = '1'
                        } else {
                            head.check = '2'
                        }
                    }
                })
            }
        }
    }
}
</script>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值