当前位置: 首页 > 工具软件 > AntD Admin > 使用案例 >

vue antd admin 表格拖拽

东郭兴学
2023-12-01

最近在使用vue antd admin做后台管理,由于vue2版本的antd vue表格组件没有拖拽功能,所以使用sortablejs实现一下,特此记录

插件官网

点这里查看官网: sortablejs官网

下载和引用

1.npm install sortable.js --save
2.import Sortable from ‘sortablejs’

代码

StandardTable.vue(表格组件封装)

<template>
	<div class="standard-table">
		<div class="alert">
			<a-alert type="info" :show-icon="true" v-if="selectedRows">
				<div class="message" slot="message">
					已选择&nbsp;
					<a>{{ selectedRows.length }}</a>
					&nbsp;项
					<a class="clear" @click="onClear">清空</a>
					<template v-for="(item, index) in needTotalList">
						<div v-if="item.needTotal" :key="index">
							{{ item.title }}总计&nbsp;
							<a>{{ item.customRender ? item.customRender(item.total) : item.total }}</a>
						</div>
					</template>
				</div>
			</a-alert>
		</div>
		<div ref="Scheduling">
			<a-table
				:bordered="bordered"
				:loading="loading"
				:columns="columns"
				:dataSource="dataSource"
				:rowKey="rowKey"
				:pagination="pagination"
				:expandedRowKeys="expandedRowKeys"
				:expandedRowRender="expandedRowRender"
				:customRow='customRow'
				@change="onChange"
				:rowSelection="selectedRows ? { selectedRowKeys: selectedRowKeys, onChange: updateSelect } : undefined"
			>
				<template slot-scope="text, record, index" :slot="slot" v-for="slot in Object.keys($scopedSlots).filter(key => key !== 'expandedRowRender')">
					<slot :name="slot" v-bind="{ text, record, index }"></slot>
				</template>
				<template :slot="slot" v-for="slot in Object.keys($slots)">
					<slot :name="slot"></slot>
				</template>
				<template slot-scope="record, index, indent, expanded" :slot="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''">
					<slot v-bind="{ record, index, indent, expanded }" :name="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"></slot>
				</template>
			</a-table>
		</div>
	</div>
</template>

<script>
import Sortable from 'sortablejs';
export default {
	name: 'DragTable',
	props: {
		bordered: Boolean,
		loading: [Boolean, Object],
		columns: Array,
		dataSource: Array,
		rowKey: {
			type: [String, Function],
			default: 'key'
		},
		pagination: {
			type: [Object, Boolean],
			default: true
		},
		selectedRows: Array,
		expandedRowKeys: Array,
		expandedRowRender: Function,
		customRow: Function
	},
	data() {
		return {
			needTotalList: []
		};
	},
	mounted() {
		this.$nextTick(() => {
			this.rowDrop();
		});
	},
	methods: {
		rowDrop() {
			const tbody = this.$refs.Scheduling.querySelectorAll('.ant-table-tbody'); // 元素选择器名称根据实际内容替换
			Sortable.create(tbody[0], {
				sort: true,
				handle: '.dragSort', //指定哪个类名的可以拖动
				// chosenClass: 'beforLine', //被选中项的css 类名
				// dragClass: "sortableDrag", //被拖拽项的css 类名
				group: { name: 'name', pull: true, put: true },
				onEnd: ({ newIndex, oldIndex }) => {
					if (newIndex == oldIndex) return;
					const currRow = this.dataSource.splice(oldIndex, 1)[0];
					this.dataSource.splice(newIndex, 0, currRow);
					let ids = this.dataSource
						.map(item => {
							return item.id;
						})
						.join(',');
					this.$emit('dragSort',ids)
				}
			});
		},
		updateSelect(selectedRowKeys, selectedRows) {
			this.$emit('update:selectedRows', selectedRows);
			this.$emit('selectedRowChange', selectedRowKeys, selectedRows);
		},
		initTotalList(columns) {
			const totalList = columns
				.filter(item => item.needTotal)
				.map(item => {
					return {
						...item,
						total: 0
					};
				});
			return totalList;
		},
		onClear() {
			this.updateSelect([], []);
			this.$emit('clear');
		},
		onChange(pagination, filters, sorter, { currentDataSource }) {
			this.$emit('change', pagination, filters, sorter, { currentDataSource });
		}
	},
	created() {
		this.needTotalList = this.initTotalList(this.columns);
	},
	watch: {
		selectedRows(selectedRows) {
			this.needTotalList = this.needTotalList.map(item => {
				return {
					...item,
					total: selectedRows.reduce((sum, val) => {
						return sum + val[item.dataIndex];
					}, 0)
				};
			});
		}
	},
	computed: {
		selectedRowKeys() {
			return this.selectedRows.map(record => {
				return typeof this.rowKey === 'function' ? this.rowKey(record) : record[this.rowKey];
			});
		}
	}
};
</script>

<style scoped lang="less">
.standard-table {
	.alert {
		margin-bottom: 16px;
		.message {
			a {
				font-weight: 600;
			}
		}
		.clear {
			float: right;
		}
	}
}
/deep/.ant-table-row {
	position: relative;
	&.afterLine:after {
		content: '';
		display: block;
		position: absolute;
		width: 100%;
		height: 0;
		border-top: 1px dashed #ff528b;
		bottom: 0;
		left: 0;
		z-index: 3;
	}
	&.sortableDrag:after {
		content: '';
		display: block;
		position: absolute;
		width: 100%;
		height: 0;
		border-top: 1px dashed #ff528b;
		top: 0;
		left: 0;
		z-index: 3;
	}
}
</style>

使用

<template>
	<div class="stickyClassify">
		<a-card>
			<!-- 表格 -->
			<standard-table
				:columns="classifyColumns"
				:data-source="tableData"
				:pagination="pagination"
				style="margin-top:20px"
				@dragSort="dragSort"
				:drag="true"
				bordered
				:rowKey="
					record => {
						return record.id;
					}
				"
			>
				<div slot="sort" slot-scope="{ record, index }" style="cursor:grab;" class="dragSort">
					<a-icon type="flag" />
					{{ index + 1 }}
				</div>
				<div slot="options" class="option"><a>编辑</a></div>
			</standard-table>
		</a-card>
	</div>
</template>

<script>
import StandardTable from '@/components/table/StandardTable';
const classifyColumns = [
	{
		title: '序号',
		scopedSlots: { customRender: 'sort' },
		align: 'center'
	},
	{
		title: '名称',
		dataIndex: 'name',
		align: 'center'
	},
	{
		title: '操作',
		scopedSlots: { customRender: 'options' },
		align: 'center'
	}
];
export default {
	components: { StandardTable },
	data() {
		return {
			pagination: {
				current: 1,
				total: 0
			}, //分页数据
			tableData: [],
			classifyColumns
		};
	},
	mounted() {
		this.tableData = [
			{
				name: '示例1',
				id: 1
			},
			{
				name: '示例2',
				id: 2
			},
			{
				name: '示例3',
				id: 3
			},
			{
				name: '示例4',
				id: 4
			},
			{
				name: '示例5',
				id: 5
			}
		];
	},
	methods:{
		dragSort(){
			//拖拽完成后做些什么
		}
	}
};
</script>

<style lang="less" scoped>
.option .option-btn {
	color: #ff6396;
	padding: 0px 10px;

	&:nth-of-type(2) {
		border-left: 1px solid #ff6396;
		border-right: 1px solid #ff6396;
	}
}
</style>

需要的朋友可以参考一下

 类似资料: