记录:点击el-table表格操作列中复制按钮,复制该行数据

一、需求

点击表格操作列的操作按钮,弹出弹窗确认后可复制该行数据,表格随之增加一行
在这里插入图片描述
在这里插入图片描述

二、思路(自己做的有点笨)

  1. 点击操作列的按钮时都会获取到当前行的信息;
  2. 在按钮的点击函数中控制复制弹窗的显示,定义一个收集表单信息的对象,里面的字段和你表格的需要一致;
  3. 将点击某一行后拿到的该行的数据进行修改,因为复制的信息不能和原本的一样需要做区别,修改之后直接赋值给对象的对应字段,这样点击确认时就能得到和原来的行一样的数据;
  4. 最后将新复制的数据在submit的函数中保存到后端

三、实现

这里table是子组件进行引入

            <div class="table">
                <Table :columns="tableColumns" :data="equipmenytArray" :tabletype="tableType" :operationsButtons="buttonsData"
                    :total="pageTotal" @showComponents="showComponents"></Table>
            </div>

父组件中的showComponents函数:

//根据操作按钮展示不同组件
const showComponents =  (val,index)=>{
    console.log('子btns',val,index)//val就是点击的该行的信息
    if(val.label == '查看'){
        router.push({
            path:'/detail/index',
            // name:'数据详情',
            query: {
                id:val.id || val.projectID,
            }
        })
    }
    if(val.label == '删除'){
        ElMessageBox.confirm('确定要删除嘛?', '提示', {
            confirmButtonText: '删除',
            cancelButtonText: '取消',
            type: 'warning',
        }).then(() => {
            //从表格中删除对应数据
            equipmenytArray.value = equipmenytArray.value.filter(obj => obj.id !== val.id)
            pageTotal.value = equipmenytArray.value.length
            store.commit('Del_EquipmentID',val.id)
            //调用接口删除数据库中的数据
            deleteEquipment(val.id)
        }).catch(() => {
            
        });
    }
    if(val.label == '复制'){
        copyShow.value = true
        //对id和name进行修改以便区别
        dialogtitle.value = '复制设备信息'
        const equipID = val.id + '_1'
        const equipName  = val.name + '_1'
        const createTime = getCurrentDate() //创建时间
        //这里我不仅需要复制这一行,还有这一行代表的设备的附带所有设备属性,是一个单独的表格内容
        getEquipAttrs(val.id).then((response)=>{
            console.log(response.data)
            response.data.data.id = equipID
            saveEquipAttrs(response.data.data).then((res)=>{
                // console.log(res.data)
                store.commit('SET_AttrsData',res.data.attrs)
            })
            console.log('导入成功')
            // ElMessage.success('复制成功')
        })
        //这是定义的收集表单的对象,当复制弹窗弹出时里面默认会有id和name,可自行修改,addTime是当前时间,其他字段都是和原来的行数据一样的
        const indexgroupData = { 
            id:equipID, 
            name:equipName,
            deviceSuper:val.deviceSuper,
            addTime:createTime,
            creator:val.creator,
            manufacturers:val.manufacturers,
            modelNumber:val.modelNumber,
        }
        //传递给子组件
        formData.value = indexgroupData
    }
}

父组件的submit函数,这里提交弹窗收集的表单数据并调用接口进行存储

//提交新建表单
const handleSubmit = async () => {
    console.log('formData',formData.value)
    attrDevice.value.push({
        label:formData.value.id,
        value:formData.value.name,
    })
    dialogVisible.value = false
    importdialogVisible.value = false
    copyShow.value = false
    //因为每个操作按钮提交表单不一样所以做个判断
    //提交的是新建表单进行保存
    if(!formData.value.hasOwnProperty('attrs') ){
        saveEquipmentInfo(formData.value).then(response=>{
            console.log(response.data)
            equipmenytArray.value.push(response.data)
            store.commit('SET_EquipmentData',equipmenytArray.value)
            store.commit('SET_EquipmentID',response.data.id)
            pageTotal.value = equipmenytArray.value.length
        }).catch((error)=>{
            console.error('请求出错',error)
        })
    }else{ //提交的是属性表单
        // store.commit('SET_AttrsData',formData.value.attrs)
        let resultAttrs = await saveEquipAttrs(formData.value)
        console.log('resultAttrs',resultAttrs)
        store.commit('SET_AttrsData',resultAttrs.data.attrs)
        ElMessage.success('导入成功')
    }
}

四、所有代码

  1. table的
<template>
    <div>
        <el-table :data="tableData" :row-key="getRowKey" :default-sort="{ prop: 'id', order: 'ascending' } "
            selection-type="multiple" @selection-change="handleSelectionChange" ref="table" 
            :row-class-name="rowStyle" id="eltable" max-height="450px" :header-cell-style="{background:'#f5f5f5'}">
            <el-table-column :type="tabletype" width="55" align="center"></el-table-column>
            <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
                :width="column.width" :filters="column.filters" :filter-method="filterMethod">
            </el-table-column>
            <el-table-column label="操作" width="180" v-if="showOperate" fixed="right">
                <template #default="{ row , $index }">
                    <el-button-group class="btns">
                        <el-button v-for="button in operationsButtons" :key="button.label" size="small"
                            :style="button.style" @click="() => handleOperation(row, button, $index)">
                            <template v-if="button.type == 'text'">
                                {{ button.label }}
                            </template>
                            <template v-if="button.type == 'img'">
                                <img :src="button.icon" style="width:18px;height:18px;" />
                            </template>
                        </el-button>
                    </el-button-group>
                </template>
            </el-table-column>
        </el-table>
        <div>
            <!-- 分页 -->
            <el-pagination :locale="locale" background class="pagination" small :page-sizes="pageSizesArr"
                @size-change="sizeChange" @current-change="currentChange" :current-page="current" :page-size="size"
                :total="total" :layout="layout" />
        </div>
    </div>
</template>

<script setup>
// import { setStore} from '../../utils/store'
// import {ElMessageBox } from 'element-plus';
import { ref, computed, defineProps, onMounted   } from 'vue';

const table = ref(null)
const size = ref(10)
const selectedRows = ref([]);
const dialogVisible = ref(false)
//接收父组件传递过来的数据
const props = defineProps({
    columns: {
        type: Array,
        required: true,
    },
    tabletype:{
        type:String,
        default:'',
    },
    data: {
        type: Array,
        required: true,
    },
    operationsButtons: {
        type: Array,
        required: true,
        default:''
    },
    total: {
        type: Number,
        // 类型
        required: true,
        default: 0,
    },
    // 分页的页容量数组
    pageSizesArr: {
        type: Array,
        default() {
            return [10, 20, 30, 50];
        },
    },
    // 分页的布局
    layout: {
        type: String,
        default: "total, sizes, prev, pager, next, jumper",
    },
    showOperate: {
        type: Boolean,
        default: true,
    },
});

//通过emits 和父组件进行通信
const emits = defineEmits(["sizeChange", "currentChange", "openDrawer",'showComponents']);

function handleSelectionChange(selection) {
    selectedRows.value = selection;
}
const tableData = computed(() => props.data);

onMounted(()=>{
    // console.log(table.value.getSelectionRows())
})

// 处理操作按钮点击事件
function handleOperation(row, button ,index) {
    // console.log(index)
    dialogVisible.value = true
    row.label = button.label
    console.log('row',row)
    emits("showComponents", row,index);
}

function getRowKey(row) {
    return row.id;
}

// 页数改变的时候触发的事件
const sizeChange = (val) => {
    emits("sizeChange", val);
}
// 当前页改变的时候触发的事件
const currentChange = (val) => {
    emits("currentChange", val);
}
//可忽略,这是我在另一个页面引用这个子组件所需要的
const rowStyle = ({row})=>{
    // console.log(row)
    if(row.alarmLevel=== '一级'){
        return 'alarm-one-level'
    }else if(row.alarmLevel=== '二级'){
        return 'alarm-two-level'
    }else if(row.alarmLevel=== '三级'){
        return 'alarm-three-level'
    }
}

const filterMethod =(value,row,column)=>{
    const property = column['property']
    return row[property] === value
}

</script>

<style>
.pagination {
  float: right;
  margin-top: 1.25rem;
  margin-bottom: 1.25rem;
}

.el-table .alarm-one-level{
    color: #DC143C;
    /* background-color:#DC143C; */
}
.el-table .alarm-two-level{
    color: #FFD700;
    /* background-color: #FFD700; */
}
.el-table .alarm-three-level{
    color: #F4A460;
    /* background-color: #F4A460; */
}

.btns{
    display: flex;
    margin-right: 5px;
}
</style>
  1. 父组件
<template>
        <div>
            <div class="table">
                <Table :columns="tableColumns" :data="equipmenytArray" :tabletype="tableType" :operationsButtons="buttonsData"
                    :total="pageTotal" @showComponents="showComponents"></Table>
            </div>
        </div>
        <DialogForm v-model="dialogVisible" :dialogtitle="dialogtitle"  v-model:form-data="formData"
            @submit="handleSubmit" :formItems="formItems" :selectData="selectData" :propertyData="dataOfTree"/>
        <ImportDialog v-model="importdialogVisible" :dialogtitle="importdialogtitle" v-model:form-data="formData"
            @submit="handleSubmit" :formItems="attributeItems">
        </ImportDialog>
        //这里不需要再引入一个dialog,用上面DialogForm 这个即可,可删除这一部分多余了。然后在showComponents 的复制if中,直接用dialogVisible、dialogtitle、formItems这几个变量即可
        <CopyForm v-model="copyShow" :dialogtitle="dialogtitle"  v-model:form-data="formData"
            @submit="handleSubmit" :formItems="copyInfoItems"></CopyForm>
</template>
<script setup>
import { useStore } from "vuex"
import { ref, onMounted } from 'vue'
import { useRouter} from 'vue-router'
import { getStore,setStore } from "utils/store";
import Table from './TableComponent.vue'
// import detailTable from "./detailTable.vue"
import ImportDialog from './importDialog.vue'
import {ElMessageBox,ElMessage} from 'element-plus'
import { generateUniqueCode } from '../../utils/uuid'
import { getCurrentDate } from '../../utils/datehandle.mjs'
import CopyForm from '../../components/dialog/addDialog.vue'
import { handleTreeData } from '../../utils/arrayTotreeData'
import DialogForm from '../../components/dialog/addDialog.vue'
import  { formItemsDevice,copyInfoItems } from './staticConfigData/powerstation'
import { saveEquipmentInfo, delDeviceById, getAllProperty,saveEquipAttrs ,getEquipAttrs} from '@/api/equipmentManageApi'

//变量定义 

const dialogtitle = ref('') //模态框标题
const dialogVisible = ref(false)//模态框显示与否
const equipmenytArray = ref([]) //设备
const formItems = ref([]) //模态框组件各个小组件标签
const formData = ref({}) //模态框组件表单数据
const copyShow = ref(false) //复制模态框显示与否
// const copydialogtitle = ref('')
const attrDevice = ref([])
const dataOfTree = ref([])
const pageTotal = ref(0)
const equipmentName = ref([])

const attributeItems = ref([
    { label: "选择设备", prop: "id", type: "select" ,options:equipmentName.value},
    { label: "导入属性", prop: "attrs", type: "upload" },
])

//表格表头
const tableColumns = [
    { prop: 'id', label: '标识',width:120 },
    { prop: 'name', label: '设备名称',width:200 },
    { prop: 'deviceSuper', label: '所属资产',width:250 },
    { prop: 'manufacturers', label: '厂家',width:220 },
    { prop: 'modelNumber', label: '型号',width:120 },
    { prop: 'addTime', label: '新增时间',width:200 },
    { prop: 'creator', label: '创建人',width:120 },
];

//表格操作按钮,表格的操作按钮可由父组件传入,数量,图标,大小可自定义
const buttonsData = [
    { label: '查看', type: 'img', style:'border-radius:3px;width:20px;margin:0px 5px', icon: '/img/check.png' },
    { label: '编辑', type: 'img', style:'border-radius:3px;width:20px;margin:0px 5px', icon: '/img/edit.png' },
    { label: '删除', type: 'img', style:'border-radius:3px;width:20px;margin:0px 5px', icon: '/img/del.png' },
    { label: '复制', type: 'img', style:'border-radius:3px;width:20px;margin:0px 5px', icon: '/img/copy.png' },
]

onMounted(()=>{
    const handledata = store.state.project.projectData
    dataOfTree.value = handleTreeData(handledata)
    console.log('dataOfTree',dataOfTree.value)
    const allId = getStore({ name:'equipmentID' })
    getData(allId)
})
//下拉选择框事件
const changeSelectValue = (val)=>{
    inputPlaceholder.value = val
}

//获取数据
const getData = async (id) =>{
    console.log(id)
    let result = await getAllProperty(id)
    console.log('result',result)
    if(Array.isArray(result.data)){
        equipmenytArray.value = result.data
        equipmenytArray.value.map(item=>{
            equipmentName.value.push({
                label:item.name,
                value:item.id
            })
        })
    }
    store.commit('SET_EquipmentData',equipmenytArray.value)
}

//新增设备
const addDevice = ()=>{
    dialogVisible.value = true
    dialogtitle.value = '新增设备'
    const uniquecode = generateUniqueCode() //设备唯一标识
    const createTime = getCurrentDate() //创建时间
    const creator =  store.state.user.userInfo.username  //获取当前用户
    const indexgroupData = { pip:'2', id: uniquecode ,name:'',deviceSuper:'',manufacturers:'' ,modelNumber:'',addTime:createTime,creator:creator}
    formItems.value = formItemsDevice
    formData.value = indexgroupData
}

//提交新建表单
const handleSubmit = async () => {
    console.log('formData',formData.value)
    attrDevice.value.push({
        label:formData.value.id,
        value:formData.value.name,
    })
    dialogVisible.value = false
    importdialogVisible.value = false
    copyShow.value = false
    //提交的是新建表单进行保存
    if(!formData.value.hasOwnProperty('attrs') ){
        saveEquipmentInfo(formData.value).then(response=>{
            console.log(response.data)
            equipmenytArray.value.push(response.data)
            store.commit('SET_EquipmentData',equipmenytArray.value)
            store.commit('SET_EquipmentID',response.data.id)
            pageTotal.value = equipmenytArray.value.length
        }).catch((error)=>{
            console.error('请求出错',error)
        })
    }else{ //提交的是属性表单
        // store.commit('SET_AttrsData',formData.value.attrs)
        let resultAttrs = await saveEquipAttrs(formData.value)
        console.log('resultAttrs',resultAttrs)
        store.commit('SET_AttrsData',resultAttrs.data.attrs)
        ElMessage.success('导入成功')
    }
}

//删除数据
const deleteEquipment = async (id) => {
    try {
        await delDeviceById(id);
        console.log('删除成功');
        ElMessage.success('删除成功')
    } catch (error) {
        console.error('删除失败', error);
        ElMessage.error('删除失败')
    }
};

//根据操作按钮展示不同组件
const showComponents =  (val,index)=>{
    console.log('子btns',val,index)
    if(val.label == '查看'){
        router.push({
            path:'/detail/index',
            // name:'数据详情',
            query: {
                id:val.id || val.projectID,
            }
        })
    }
    if(val.label == '删除'){
        ElMessageBox.confirm('确定要删除嘛?', '提示', {
            confirmButtonText: '删除',
            cancelButtonText: '取消',
            type: 'warning',
        }).then(() => {
            //从表格中删除对应数据
            equipmenytArray.value = equipmenytArray.value.filter(obj => obj.id !== val.id)
            pageTotal.value = equipmenytArray.value.length
            store.commit('Del_EquipmentID',val.id)
            //调用接口删除数据库中的数据
            deleteEquipment(val.id)
        }).catch(() => {
            
        });
    }
    if(val.label == '复制'){
        dialogVisible.value = true
        dialogtitle.value = '复制设备信息'
        const equipID = val.id + '_1'
        const equipName  = val.name + '_1'
        const createTime = getCurrentDate() //创建时间
        getEquipAttrs(val.id).then((response)=>{
            console.log(response.data)
            response.data.data.id = equipID
            saveEquipAttrs(response.data.data).then((res)=>{
                // console.log(res.data)
                store.commit('SET_AttrsData',res.data.attrs)
            })
            console.log('导入成功')
            // ElMessage.success('复制成功')
        })
        const indexgroupData = { 
            id:equipID, 
            name:equipName,
            deviceSuper:val.deviceSuper,
            addTime:createTime,
            creator:val.creator,
            manufacturers:val.manufacturers,
            modelNumber:val.modelNumber,
        }
        formData.value = indexgroupData
        //copyInfoItems这个是单独定义在一个js中引入的
        formItems.value = copyInfoItems
    }
}

//导入单个设备属性
const importAttr = ()=>{
    importdialogVisible.value = true
    importdialogtitle.value = '导入设备属性'
}

//批量导入设备属性
const importAttrs = () =>{
    importdialogVisible.value = true
    importdialogtitle.value = '批量导入设备属性'
    attributeItems.value[0].type = 'mulselect'
    const deviceData = store.state.project.equipmentData
    const handledata = store.state.project.projectData
    const multiSelect = handleTreeData(deviceData)
    console.log('deviceData',deviceData)
    console.log('multiSelect',multiSelect)
}

</script>

<style scoped lang="scss">

.search{

    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-top: 10px;
    .btns{
        margin-left: 10px;
    }
}

</style>

const copyInfoItems = [
    { label: "设备标识", prop: "id", type: "input" },
    { label: "设备名称", prop: "name", type: "input" },
];
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值