字段选择、是否固定、宽度、类型都在showDataList中配置
组件封装
<template> <el-popover placement="top" v-model="visible"> <div class="test_wrapper" @dragover="dragover($event)"> <div class="text">字段设置</div> <el-divider></el-divider> <transition-group class="transition-wrapper" name="sort"> <div v-for="(item, index) in dataList" :key="item.id" class="bottom-botton" :draggable="true" @dragstart="dragstart(item)" @dragenter="dragenter(item, $event)" @dragend="dragend(item, $event)" @dragover="dragover($event)" > <div style="width:110px"> <el-checkbox style="margin-right: 10px" v-model="dataList[index].isture" @change="rediochange"></el-checkbox>{{ item.label }} </div> <div style="width:100px;"> <template> <span class="F666 text12">是否固定</span> <el-switch v-model="item.fixed" @change="switchChange" active-color="#257FEA" inactive-color="#E1E3E6"></el-switch> </template> </div> <div> <i class="el-icon-bottom" @click="tableConfigMove('down',index)"></i> <i class="el-icon-top" @click="tableConfigMove('up',index)"></i> </div> </div> </transition-group> </div> <div class="bottom-botton"> <span style="text-align: left; margin: 0"> <el-button size="mini" type="plain" icon="el-icon-refresh-right" @click="saveTableHead()" >一键恢复</el-button > </span> <span style="text-align: right; margin: 0"> <el-button size="mini" type="text" @click="visible = false" >取消</el-button > <el-button type="primary" size="mini" @click="saveTableConfig" >确定</el-button > </span> </div> <el-button v-if="visibleclose" @click="visclose" slot="reference" icon="el-icon-s-fold" type="primary">列设置 </el-button> <el-button v-if="visibleon" @click="vison" slot="reference" icon="el-icon-s-unfold" type="primary">列设置 </el-button> <!-- <i v-if="visibleon" @click="vison" slot="reference" class="el-icon-s-unfold" ></i> --> <!--<el-button slot="reference">删除</el-button>--> </el-popover> </template> <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> <script> import {tableField} from "@/api/customer" import draggable from "vuedraggable"; import Sortable from "sortablejs"; export default { components: { draggable, Sortable }, props:{ dataList: { type: Array, default: () => { return [] } }, title: { type: String, default: '' } }, data() { return { visible: false, visibleclose: true, visibleon: false, name: null, oldData: null, newData: null, dataLists: this.dataList, tableConfigData:[], } }, mounted(){ console.log('dataList', this.dataList,this.title) }, methods: { //表格排序变化 tableConfigMove(direction, index){ console.log('dataList',direction,index) if (direction == 'up') { this.dataList[index] = this.dataList.splice(index - 1, 1, this.dataList[index])[0]; } else if (direction == 'down') { this.dataList[index + 1] = this.dataList.splice(index, 1, this.dataList[index + 1])[0]; } }, saveTableConfig() { console.log('saveTableConfig',this.dataList,'this.title',this.title) let data = { title:this.title, fields:this.dataList, used_fields:this.dataList, used:2 } tableField(data).then(res=>{ console.log('tableField',res) if(res.code == 0){ this.$message.success('保存成功') this.$emit('showListField') this.visible = false } }) }, switchChange(val) { console.log('switchChange',val) }, saveTableHead() { this.$emit('dataList', this.dataList) let data = { title:'公海显示字段', fields:this.dataList, used_fields:this.dataList, used:1 } tableField(data).then(res=>{ console.log('tableField',res) if(res.code == 0){ } }) this.$emit('showListField',true) }, // 拖拽事件 handleEdit(index, row) { console.log('handleEdit',index, row); }, handleDelete(index, row) { console.log(index, row); }, dragstart(value) { this.oldData = value; }, // 记录移动过程中信息 dragenter(value, e) { this.newData = value; e.preventDefault(); }, // 拖拽最终操作 dragend(value, e) { if (this.oldData !== this.newData) { let oldIndex = this.dataList.indexOf(this.oldData); let newIndex = this.dataList.indexOf(this.newData); let newItems = [...this.dataList]; // 删除老的节点 newItems.splice(oldIndex, 1); // 在列表中目标位置增加新的节点 newItems.splice(newIndex, 0, this.oldData); this.dataList = [...newItems]; this.$emit("radio",this.dataList); console.log('dataList',this.dataList) } }, // 上移 moveUp(index, row) { console.log("上移", index, row); if (index > 0) { const upDate = this.dataList[index - 1]; this.dataList.splice(index - 1, 1); this.dataList.splice(index, 0, upDate); } else { alert("已经是第一条,不可上移"); } }, // 下移 moveDown(index, row) { console.log("下移", index, row); if (index + 1 === this.dataList.length) { alert("已经是最后一条,不可下移"); } else { const downDate = this.dataList[index + 1]; this.dataList.splice(index + 1, 1); this.dataList.splice(index, 0, downDate); } }, // 拖动事件(主要是为了拖动时鼠标光标不变为禁止) dragover(e) { e.preventDefault(); }, // 拖拽事件结束 // 点击展开拖拽框 visclose() { console.log('this.initTableConfig',this.dataList) this.visibleclose = false; this.visibleon = true; }, //点击关闭拖拽框 vison() { this.$emit('showListField',true) this.visibleclose = true; this.visibleon = false; }, rediochange() { this.$emit("radio", this.dataList) } } }; </script> <style scoped lang="scss"> @import '../../../styles/variables.scss'; @import '../../../styles/mixin.scss'; .bottom-botton { width: 350px; @include flex-middle-between; } .test_wrapper { // padding-top: 20px; // width: 270px; /*background-color: pink;*/ } .el-divider--horizontal { margin: 15px 0; } .test_wrapper .text { font-size: 16px; margin-left: 20px; color: #0e0e9d; } .transition-wrapper { display: inline-block; // margin-left: 20px; } .transition-wrapper .sort-item { // margin-bottom: 6px; } </style>
使用实例:
<dragList @radio="ssss" @showListField='zzzz' :dataList="showDataList1" v-if="showDataList1" :title="uesdTitle" style="margin-left:10px"></dragList>
<el-table
v-if="asa"
:data="tableData"
row-key="id"
border
v-loading.body="loading"
ref="tableRef"
v-horizontal-scroll="'always'"
:header-cell-style="{
background: '#eef1f6',
color: '#606266'
}"
@selection-change="handleSelectionChange2"
@sort-change="onSortChange">
<template v-for="column in showDataList1">
<el-table-column v-if="column.id==0" type="selection"></el-table-column>
<el-table-column v-else-if="column.id==10" sortable label="创建时间">
<template slot-scope="scope">{{scope.row.create_time?scope.row.create_time:'--'}}</template>
</el-table-column>
<el-table-column v-else-if="column.id==11" sortable label="最近跟进时间">
<template slot-scope="scope">{{scope.row.update_time?scope.row.update_time:'--'}}</template>
</el-table-column>
<el-table-column v-else-if="column.id==12" sortable label="放弃客户时间">
<template slot-scope="scope">{{scope.row.fail_time?scope.row.fail_time:'--'}}</template>
</el-table-column>
<el-table-column v-else-if="column.id==14" label="操作" fixed="right">
<template slot-scope="scope">
<span fixed="right">
<el-button v-if="checkPermission(['larke-admin.larke-admin.company.opensea.goout'])" type="text" @click="outClick(scope.$index, scope.row)">转出</el-button>
<el-button v-if="checkPermission(['larke-admin.company.customer.edit'])" type="text" @click="editClick(scope.$index, scope.row)">跟进</el-button>
<el-button v-if="checkPermission(['larke-admin.opensea.delete'])" type="text" @click="delClick(scope.$index, scope.row)">删除</el-button>
</span>
</template>
</el-table-column>
<template v-else>
<el-table-column
:key="column.id"
:prop="column.prop"
v-if="column.isture"
:class-name="column.isDrag"
:label="column.label"
:align="column.align"
:type="column.type"
:fixed="column.fixed"
:width="column.width">
<template slot-scope="scope">
<template v-if="column.id == 13">
<div style="color:#13ce66" v-if="scope.row.phone_call_count > 0">已联系</div>
<div style="color:#ff4949" v-else>未联系</div>
</template>
<template v-else-if="column.id == 1">
{{scope.$index+1}}
</template>
<template v-else>
{{scope.row[column.prop]?scope.row[column.prop]:'--'}}
</template>
</template>
</el-table-column>
</template>
</template>
</el-table>
<script>
import { getTableField} from '@/api/customer'
export default{
components: {JstTable},
data(){
showDataList: [
{
id: "0",
type: "selection",
width: "55",
align: "center",
isture: false,
fixed: true, //是否固定
},
{
id: "1",
type: "index",
label: "序号",
prop: "order_name",
align: "center",
scope: "scope",
isture: true,
fixed: true, //是否固定
},
{
id: "2",
label: "客户名称",
width:"140",
prop: "customer_name",
align: "center",
isDrag: "drag",
isture: true,
fixed: true, //是否固定
},
{
id: "3",
label: "手机号",
width:"140",
prop: "mobile",
align: "center",
isDrag: "drag",
isture: true,
fixed: true, //是否固定
},
{
id: "4",
label: "企业名称",
width:"120",
prop: "business_name",
align: "center",
isDrag: "drag",
scope: "ClientTag",
isture: true,
fixed: true
},
{
id: "6",
label: "最新跟进记录",
width: "200",
prop: "latest_context",
align: "center",
isture: true,
fixed: false
},
{
id: "6",
label: "标签",
width: "120",
prop: "labels",
align: "center",
isture: true,
fixed: false
},
{
id: "7",
label: "区域",
width: "120",
prop: "mydistrict",
align: "center",
isture: true,
fixed: false
},
{
id: "8",
label: "来源",
prop: "channel",
align: "center",
isture: true,
fixed: false
},
{
id: "9",
label: "线索类型",
prop: "clue_type",
align: "center",
isture: true,
fixed: false
},
{
id: "10",
label: "创建时间",
prop: "create_time",
sortable:true,
align: "center",
isture: true,
fixed: false
},
{
id: "11",
label: "最近跟进时间",
sortable:true,
prop: "update_time",
align: "center",
isture: true,
fixed: false, //是否固定
},
{
id: "12",
label: "放弃客户时间",
sortable:true,
prop: "fail_time",
align: "center",
isture: true,
fixed: false, //是否固定
},
{
id: "13",
label: "电话联系",
prop: "phone_call_count",
align: "center",
isture: true,
fixed: false, //是否固定
},
{
id: "14",
label: "操作",
align: "center",
isture: true,
fixed: true, //是否固定
}
],
showDataList1: [],
},
methods:{
ssss(data){
this.asa = false
this.showDataList1 = data
console.log('ssssss',data,this.showDataList)
this.$nextTick(() => { //在数据加载完,重新渲染表格
this.asa = true
//this.$refs['tableRef'].doLayout();
})
},
zzzz(data) {
console.log('zzzz',data)
this.showDataField(data)
},
}
}
</script>
在写组件的时候,写一键恢复功能,发现前端无法保存初始数据,也就是说无法一键恢复,采用在数据保存发给后端的时候把初始数据也发给后端同时传过去一个字段used,再次调用的时候判断used字段,1为还没有设置配置字段,2为已经配置了显示字段。通过字段拉取响应列表。后端返回设置过后的字段列表和初始列表。