表格数据穿梭框,左侧选择完之后禁止选择,右侧删除后左侧恢复选择

上代码(可作为组件封装使用,记得修改数据源,我是接口请求的数据,没有模拟数据):

<el-dialog title="选择需求名称" append-to-body :visible.sync="dialogVisible" width="90%" :show-close="false" :close-on-click-modal="false">
        <el-row type="flex" class="row-bg" justify="space-between">
            <el-col :span="11">
                <vxe-table resizable ref="xTable2" border show-overflow highlight-hover-row :loading="loading1" :data="leftTableData" height="500"
                @checkbox-change="selectChangeEvent" @checkbox-all="selectAllEvent" :checkbox-config="{ checkMethod: checkCheckbox }">
                    <vxe-table-column type="checkbox" fixed="left" width="60"></vxe-table-column>
                    <vxe-table-column type="seq" fixed="left" width="60"></vxe-table-column>
                    <vxe-table-column field="name" title="名称" min-width="120"></vxe-table-column>
                    <vxe-table-column field="description" title="描述" min-width="120"></vxe-table-column>
                    <vxe-table-column field="demandType" title="需求类型" min-width="100"></vxe-table-column>
                    <vxe-table-column field="fieldType" title="字段类型" min-width="100">
                        <template v-slot:default=" {row} ">
                            <div v-for="item in dictionaryList" :key="item.id">
                                <span v-if="row.fieldType == item.dictKey">{{ item.dictValue }}</span>
                            </div>
                        </template>
                    </vxe-table-column>
                    <vxe-table-column field="vaildStatus" title="校验" min-width="80">
                        <template v-slot:default=" {row} ">
                            <span>{{ row.vaildStatus === 0 ? '否' : '是' }}</span>
                        </template>
                    </vxe-table-column>
                </vxe-table>
                <!-- 分页部分 -->
                <vxe-pager background :current-page="tablePage.current" :page-size="tablePage.size" :total="tablePage.totalElements"
                    :page-sizes="[10, 30,50,100]" :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
                    @page-change="handlePageChange">
                </vxe-pager> 
            </el-col>
            <el-col :span="2">
                <div class="icon-arrow">
                    <div class="el-icon-arrow-right" @click="goRight()"></div>
                    <!-- <div class="el-icon-arrow-left"></div> -->
                </div>
            </el-col>
            <el-col :span="11">
                <div style="margin-bottom: 10px;">已选 <span style="color: #499eff;">{{ rightTableData.length }}</span> 项</div>
                <vxe-table resizable ref="xTable3" border show-overflow highlight-hover-row :loading="loading2" :data="rightTableData" height="500">
                    <vxe-table-column type="seq" fixed="left" width="60"></vxe-table-column>
                    <vxe-table-column field="name" title="名称" min-width="120"></vxe-table-column>
                    <vxe-table-column field="description" title="描述" min-width="120"></vxe-table-column>
                    <vxe-table-column field="demandType" title="需求类型" min-width="100"></vxe-table-column>
                    <vxe-table-column field="fieldType" title="字段类型" min-width="100">
                        <template v-slot:default=" {row} ">
                            <div v-for="item in dictionaryList" :key="item.id">
                                <span v-if="row.fieldType == item.dictKey">{{ item.dictValue }}</span>
                            </div>
                        </template>
                    </vxe-table-column>
                    <vxe-table-column field="vaildStatus" title="校验" min-width="80">
                        <template v-slot:default=" {row} ">
                            <span>{{ row.vaildStatus === 0 ? '否' : '是' }}</span>
                        </template>
                    </vxe-table-column>
                    <vxe-table-column field="id" title="操作" width="80" fixed="right" align="center">
                        <template v-slot:default="{ row }">
                            <el-button size="mini" @click="delRightBtn(row)" type="text" style="color: #f56c6c;">删除</el-button>
                        </template>
                    </vxe-table-column>
                </vxe-table>
            </el-col>
        </el-row>
        <div style="text-align: right;display: block;">
            <el-button @click="closeForm()">取消</el-button>
            <el-button type="primary" @click="submitForm()" :loading="loadingBtn">确定</el-button>
        </div>
    </el-dialog>

js部分:

<script>
import api from "@/api/rfp/index";
export default {
    data() {
        return {
            dialogVisible: false,
            loading1: false,
            loading2: false,
            leftTableData: [],
            rightTableData: [],
            selectCheckList1: [],
            tablePage: {
                total: 0,
                current: 1,
                size: 10,
                background: true,
                totalElements: 0
            },
            dictionaryList: [],
            loadingBtn: false,
            queryData: {},
            paramsData: {},
            uuId: '',
        };
    },
    created() {
        this.queryData = this.$route.query;
    },
    methods: {
        showDialog(obj){
            this.paramsData = obj;
            this.dialogVisible = true;
            this.getUuid();
            this.getLeftList();
            this.getDictionaryList();
        },
        // 获取uuId
        getUuid(){
            api.queryUuid().then((res) =>{
                this.uuId = res.data.data;
            })
        },
        // 获取字段类型字典
        getDictionaryList(){
            let params = {
                code: 'FieldType'
            }
            api.queryDictionaryTree(params).then((res) => {
                this.dictionaryList = res.data.data
            })
        },
        // 获取左侧数据
        getLeftList(){
            let params = {
                detailId: this.queryData.id,
            }
            api.queryStageDemandList(params).then((res) => {
                this.leftTableData = res.data.data;
            })
        },
        // 分页发生改变事件 totalElements
        handlePageChange({currentPage, pageSize}) {
            this.tablePage.current = currentPage;
            this.tablePage.size = pageSize;
            this.getLeftList();
        },
        // 根据字段判断是否禁用复选框
        checkCheckbox({ row }) {
            // 根据行数据的某个字段值来决定是否禁用复选框
            return !row.isBind;
        },
        // 左侧全选
        selectAllEvent ({ records }) {
            this.selectCheckList1 = records;
        },
        // 左侧单选
        selectChangeEvent ({ records }) {
            this.selectCheckList1 = records;
        },
        goRight(){
            if(this.selectCheckList1.length === 0){
                this.$message.warning('请选择左侧数据!');
                return
            }
            this.selectCheckList1.map((item) => {
                item.isBind = true;
                this.rightTableData.push(item)
            })
            this.rightTableData = [...new Set(this.rightTableData)] // 右侧数据去重
        },
        delRightBtn(row){
            //删除元素
            let index = this.rightTableData.findIndex((ele) =>{
                return ele.workStationId === row.workStationId;
            });
            this.rightTableData.splice(index,1);
            const list = this.$refs.xTable2.tableData;
            list.map((item) =>{
                if(item.workStationId === row.workStationId){
                    item.isBind = false;
                }
            });
        },
        closeForm(){
            this.dialogVisible = false;
        },
        submitForm(){
            if(this.rightTableData.length === 0){
                this.$message.warning('请先从左侧选择数据!');
                return
            }
            this.loadingBtn = true;
            let params = {
                detailId: this.queryData.id,
                stageId: this.paramsData.leftTreeId,
                demandSettingList: this.rightTableData,
            }
            api.queryUpdateDemandSetting(params,this.uuId).then(() => {
                this.$message.success('操作成功!');
                this.loadingBtn = false;
                this.dialogVisible = false;
                this.getUuid();
                this.$emit('upRightList');
            }).catch((err) => {
                this.loadingBtn = false;
                if(err.message != '点击过快,请勿重复点击!'){
                    this.getUuid();
                }
            })
        },
    }
};
</script>

style样式部分:

<style lang="scss" scoped>
.icon-arrow{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    div{
        border: 1px solid #eee;
        border-radius: 4px;
        font-size: 24px;
        padding: 5px;
    }
    div:nth-child(1){
        margin-bottom: 15px;
    }
}
</style>

至此完成!!!

测试有效!!!感谢支持!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小破孩呦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值