demo1
<template>
<div class="container">
<div class="left">
<draggable
v-model="myArray"
group="people"
@start="drag = true"
@end="drag = false"
item-key="id"
>
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</draggable>
</div>
<div class="right">
<draggable
v-model="myArray2"
group="people"
@start="drag = true"
@end="drag = false"
item-key="id"
>
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import { defineComponent, reactive, toRefs } from "vue";
import draggable from "vuedraggable";
export default defineComponent({
components: { draggable },
setup() {
const data = reactive({
drag: false,
myArray: [
{ id: 1, name: "Jenny" },
{ id: 2, name: "kevin" },
{ id: 3, name: "lili" },
],
myArray2: [
{ id: 1, name: "A" },
{ id: 2, name: "B" },
{ id: 3, name: "C" },
],
});
return { ...toRefs(data) };
},
});
</script>
<style lang="less" scoped>
.container {
display: flex;
.left {
background-color: #fff;
width: 200px;
height: 1000px;
margin: 0 20px;
padding: 20px;
.left-drag {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
min-height: 80px;
}
}
.right {
background-color: #fff;
height: 1000px;
width: 200px;
padding: 20px;
.right-drag {
width: 410px;
min-height: 80px;
display: block;
}
}
.item {
height: 40px;
border: 1px solid #e9e9e9;
text-align: center;
line-height: 40px;
margin: 20px 0;
background-color: rgb(242, 242, 242);
}
}
</style>
demo2
<template>
<div class="container">
<div class="left">
<draggable
v-model="myArray"
group="people"
@end="onDragEnd"
item-key="id"
>
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</draggable>
</div>
<div class="right">
<draggable
v-model="myArray2"
group="people"
@end="onDragEnd"
item-key="id"
>
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</draggable>
</div>
<div class="right">
<draggable
v-model="myArray3"
group="people"
@end="onDragEnd"
item-key="id"
>
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import { defineComponent, reactive, toRefs } from "vue";
import draggable from "vuedraggable";
export default defineComponent({
components: { draggable },
setup() {
const data = reactive({
myArray: Array.from({ length: 10 }, (_, i) => ({ id: i + 1, name: `Jenny${i + 1}` })),
myArray2: Array.from({ length: 10 }, (_, i) => ({ id: i + 11, name: `A${i + 1}` })),
myArray3: Array.from({ length: 5 }, (_, i) => ({ id: i + 21, name: `C${i + 1}` })),
});
const totalItems = 25;
const fixedArray3Size = 5;
const onDragEnd = () => {
balanceArrays(data.myArray, data.myArray2, data.myArray3);
};
const balanceArrays = (array1, array2, array3) => {
// 确保 array3 的大小固定
while (array3.length < fixedArray3Size) {
// 从 array1 或 array2 中取出一个元素(优先从较大的数组中取)
const sourceArray = array1.length >= array2.length ? array1 : array2;
if (sourceArray.length > 0) {
const [item] = sourceArray.splice(sourceArray.length - 1);
array3.push(item);
} else {
// 理论上不应该发生,因为 totalItems 应该总是足够分配
break;
}
}
while (array3.length > fixedArray3Size) {
// 将多余的元素放回 array1 或 array2(这里简单放回 array1,可以根据需要调整)
const [item] = array3.splice(array3.length - 1);
array1.push(item);
}
// 现在 array3 大小固定,重新分配 array1 和 array2
const remainingItems = totalItems - fixedArray3Size;
let combinedArray = [...array1, ...array2].sort((a, b) => a.id - b.id); // 按 id 排序
// 重新分配元素,尽可能平均分配到 array1 和 array2
const array1Length = Math.floor(remainingItems / 2); // 优先保证 array1 和 array2 长度接近
const array2Length = remainingItems - array1Length;
array1.length = 0;
array1.push(...combinedArray.slice(0, array1Length));
array2.length = 0;
array2.push(...combinedArray.slice(array1Length));
};
return { ...toRefs(data), onDragEnd };
},
});
</script>
<style lang="less" scoped>
.container {
display: flex;
.left, .right {
background-color: #fff;
width: 200px;
height: 1000px;
margin: 0 20px;
padding: 20px;
.item {
height: 40px;
border: 1px solid #e9e9e9;
text-align: center;
line-height: 40px;
margin: 20px 0;
background-color: rgb(242, 242, 242);
}
}
}
</style>
现实应用
<!-- 教务处 -->
<template>
<div class="but">
<el-button @click="mergeAndPrintArrays()" type="primary">保存数据</el-button>
<el-button @click="restoration()" type="primary">数据还原</el-button>
</div>
<div class="container">
<div class="left">
<el-table :data="myArray" row-key="id" ref="table1" id="table1">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="state" label="前台是否展示" width="90">
<template v-slot="scope">
<el-switch v-model="scope.row.states" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="state" label="是否作为搜索条件" width="120">
<template v-slot="scope">
<el-switch v-model="scope.row.state" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
<div class="left">
<el-table :data="myArray2" row-key="id" ref="table2" id="table2">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="state" label="前台是否展示" width="90">
<template v-slot="scope">
<el-switch v-model="scope.row.states" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="state" label="是否作为搜索条件" width="120">
<template v-slot="scope">
<el-switch v-model="scope.row.state" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
<div class="left">
<el-table :data="myArray3" row-key="id" ref="table3" id="table3">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="state" label="前台是否展示" width="90">
<template v-slot="scope">
<el-switch v-model="scope.row.states" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="state" label="是否作为搜索条件" width="120">
<template v-slot="scope">
<el-switch v-model="scope.row.state" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
<div class="left">
<el-table :data="myArray4" row-key="id" ref="table4" id="table4">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="state" label="前台是否展示" width="90">
<template v-slot="scope">
<el-switch v-model="scope.row.states" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="state" label="是否作为搜索条件" width="120">
<template v-slot="scope">
<el-switch v-model="scope.row.state" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
<div class="left">
<el-table :data="myArray5" row-key="id" ref="table5" id="table5">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="state" label="前台是否展示" width="90">
<template v-slot="scope">
<el-switch v-model="scope.row.states" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="state" label="是否作为搜索条件" width="120">
<template v-slot="scope">
<el-switch v-model="scope.row.state" @change="stateChanged(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import Sortable from "sortablejs";
import webfield from "@/api/sys/webfield";
import notifyService from "@/api/notify/notifyService";
export default {
data() {
return {
dataList: [],
earchVisible: true,
loading: false,
myArray: [],
myArray2: [],
myArray3: [],
myArray4: [],
myArray5: [],
userName: "",
userNameF: "",
companyDTO: '',
ids: '',
newtype: ''
};
},
props: ["value1"],
mounted() {
this.refreshList();
},
async created() {
var userInfo = this.$TOOL.data.get("USER_INFO");
this.userName = userInfo.id;
this.companyDTO = userInfo.companyDTO.id;
},
methods: {
// 获取数据 初始化
refreshList() {
// this.newtype = JSON.parse(this.value1)
// console.log(this.newtype, 'new11')
this.loading = true;
const params = {
officeId: this.companyDTO,
type: 1,
};
webfield.webfieldinit(params).then((data) => {
this.dataList = JSON.parse(data.data.content)
this.ids = data.data.id
console.log(data, "disa")
this.assignDataToArrays();
this.loading = false;
}).catch((error) => {
console.error('Error fetching data:', error);
this.loading = false;
});
},
// 获取数据 平均分配
assignDataToArrays() {
this.myArray = [];
this.myArray2 = [];
this.myArray3 = [];
this.myArray4 = [];
this.myArray5 = [];
// 计算每个数组应该分配的数据量
const chunkSize = Math.ceil(this.dataList.length / 5);
// 将 dataList 的数据平均分配到五个数组中
for (let i = 0; i < this.dataList.length; i++) {
if (i < chunkSize) {
this.myArray.push(this.dataList[i]);
} else if (i < chunkSize * 2) {
this.myArray2.push(this.dataList[i]);
} else if (i < chunkSize * 3) {
this.myArray3.push(this.dataList[i]);
} else if (i < chunkSize * 4) {
this.myArray4.push(this.dataList[i]);
} else {
this.myArray5.push(this.dataList[i]);
}
}
this.initSortable();
},
initSortable() {
const initSortableForTable = (tableRef, dataArray, num) => {
const tbody = this.$refs[tableRef].$el.querySelector(".el-table__body-wrapper tbody");
Sortable.create(tbody, {
onEnd: ({ newIndex, oldIndex, to, from, clone, pullMode, item }) => {
const totableid = to.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id
const fromtableid = from.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id
//id映射
const tablemap = {
table1: this.myArray,
table2: this.myArray2,
table3: this.myArray3,
table4: this.myArray4,
table5: this.myArray5,
}
if (totableid == fromtableid) {
const currRow = dataArray.splice(oldIndex, 1)[0];
dataArray.splice(newIndex, 0, currRow);
} else {
//不一致 跨列拖动
const currRow = tablemap[fromtableid].splice(oldIndex, 1)[0];
// //向to添加一个元素
tablemap[totableid].splice(newIndex, 0, currRow);
//from table会少一列
if (tablemap[totableid][newIndex + 1]) {
//如果 to table 的下一行有数据 补充回fromtable的oldindx
tablemap[fromtableid].splice(oldIndex, 0, tablemap[totableid][newIndex + 1])
//得删除to table的数据
tablemap[totableid].splice(newIndex + 1, 1)
} else if (tablemap[totableid][newIndex - 1]) {
tablemap[fromtableid].splice(oldIndex, 0, tablemap[totableid][newIndex - 1])
//得删除to table的数据
tablemap[totableid].splice(newIndex - 1, 1)
} else {
console.error("前后都没有数据 无法补充")
}
// console.log(this.myArray, this.myArray2)
}
},
group: 'zhaoxin'
});
};
initSortableForTable('table1', this.myArray);
initSortableForTable('table2', this.myArray2);
initSortableForTable('table3', this.myArray3);
initSortableForTable('table4', this.myArray4);
initSortableForTable('table5', this.myArray5);
},
//合并数组 保存数据
mergeAndPrintArrays() {
// console.log(JSON.parse(this.value1), 'oooooooooooo')
// this.newtype = JSON.parse(JSON.stringify(this.options))[0].value
this.newtype = JSON.parse(this.value1)
// 合并三个数组
const mergedArray = [...this.myArray, ...this.myArray2, ...this.myArray3, ...this.myArray4, ...this.myArray5];
const news = JSON.stringify(mergedArray);
this.loading = true;
// 构建请求参数对象
const params = {
officeId: this.companyDTO,
type: this.newtype,
content: news,
operatorId: this.userName,
};
const newparams = {
officeId: this.companyDTO,
type: this.newtype,
content: news,
operatorId: this.userName,
id: this.ids
};
if (this.ids === '') {
console.log('空啦')
webfield.webfieldadd(params).then((response) => {
location.reload(true);
this.loading = false;
}).catch((error) => {
console.error('Error fetching data:', error);
this.loading = false;
});
} else {
console.log("不空")
console.log(this.myArray, 'cuirow')
webfield.webfieldadd(newparams).then((response) => {
location.reload(true);
this.loading = false;
}).catch((error) => {
console.error('Error fetching data:', error);
this.loading = false;
});
}
},
// 控制显隐
stateChanged(row) {
const index = this.myArray.findIndex(item => item.id === row.id);
console.log('Row index:', index);
console.log('Row data:', row);
},
// 还原数据
restoration() {
this.loading = true;
console.log(this.loading, 'loading'); // 修正了拼写错误,从 'loda' 改为 'loading'
if (this.ids === '' || this.ids === undefined || this.ids === null) {
console.log('kong ')
alert('已经还原成最初的原始数据了!');
this.loading = false; // 如果不需要刷新页面,可以在这里直接设置 loading 为 false
} else {
console.log(this.ids, 'konglllll ')
webfield.webfielddel(this.ids).then((data) => {
console.log(data)
this.assignDataToArrays();
location.reload(true); // 仅在数据删除成功后刷新页面
}).catch((error) => {
console.error('Error fetching data:', error);
this.loading = false; // 请求失败时设置 loading 为 false
});
}
}
},
};
</script>
<style lang="less" scoped>
.but {
margin-bottom: 3rem;
}
.container {
display: flex;
margin-bottom: 50rem;
.left,
.right {
background-color: #fff;
width: 282px;
height: 1000px;
margin: 0 4px;
padding: 0 -8px;
.item {
height: 40px;
border: 1px solid #e9e9e9;
text-align: center;
line-height: 40px;
margin: 20px 0;
background-color: rgb(242, 242, 242);
}
}
}
</style>