vue awe-dnd+ant 自定义表格排序显隐

最近发现一个挺好用的拖拽排序插件awe-dnd ,刚好又在学习ant design,所以萌发了让table表格可自定义位置和自定义显隐的想法,用了俩个多小时把这个想法实现了。

1. 先去安装awe-dnd , awe-dnd npm链接 :https://www.npmjs.com/package/awe-dnd

$ npm install awe-dnd --save

2. 再mian.js中配置

//main.js
 
import VueDND from 'awe-dnd'
 
Vue.use(VueDND)

3. 在components 建一个drag文件夹 用来制作组件方便重复使用

 3.1 文件夹中新建drag.vue

//drag.vue

<template>


	<div>






		<a-popover :title="popoverTitle" trigger="click">
			<a slot="content">
				<div class="color-list">
					<div class="color-item" v-for="(color,index) in colors" v-dragging="{ item: color, list: colors, group: 'color' }"
					 :key="color.text">
						<a>
							<a-checkbox @change="onChange(index)" :checked="color.checked">{{color.text}}</a-checkbox>
						</a>
					</div>
				</div>

			</a>
			<a-button type="primary">{{butTitle}}</a-button>
		</a-popover>

	</div>






</template>
<script>

	export default {

		props: ['butTitle','popover' ,'columnsData', 'colorsData'],

		data() {
			return {
				butName:'',
				popoverTitle:'',
				columnsAll: [],
				columnsAllcache: {},
				colors: [],
				colorsArry: [],
				columns: []

			}
		},
		methods: {

			rf: function() {
				this.colorsArry = this.colors
				this.getDrag()
			},


			getDrag: function() {

              //columnsAllcache 用来存放全部包裹头部信息 构建以头部信息key为索引对象的数据结构

				var columnsAllcache = {}

				for (var i = 0; i < this.columnsAll.length; i++) {
					columnsAllcache[this.columnsAll[i].scopedSlots.customRender] = this.columnsAll[i]
				}

				this.columns = [] 

                //循环排序数组 获取最新文字信息和显隐信息
				for (var m = 0; m < this.colorsArry.length; m++) {

					var columnsItem = this.colorsArry[m]

					if (columnsItem.checked) { //判断排序数组中checked为选中的一项 将其放入columns 数组中 做为要展示的头部信息
						this.columns.push(columnsAllcache[columnsItem.key])
					}


				}

				this.$emit('onChange', this.columns) //触发回调方法



			},

			onChange: function(index) {
				this.colorsArry[index].checked = !this.colorsArry[index].checked
				this.getDrag()
			},

           


		},



		mounted() {
			this.$dragging.$on('dragged', ({
				value
			}) => {

				this.colorsArry = value.list
				this.getDrag()

			})
			this.$dragging.$on('dragend', () => {

			})

			this.colors = this.colorsData==undefined?[]:this.colorsData  //接收要排序的数组
			this.columnsAll = this.columnsData==undefined?[]:this.columnsData //接收表格全部的信息
			this.butName = this.butTitle==undefined?'':this.butTitle  //按钮名称
			this.popoverTitle = this.popover==undefined?'':this.popover //气泡框标题
			
			
			this.rf()
		}
	}
</script>

3.2再在文件夹下新建index.js 和drag.vue 保持一致

import Drag from './drag.vue'
export default Drag

4. 回到需要引入该组件的页面 我这里是table.vue

//table.vue

<template>


	<div>
	
<!--Drag 可配置项 butTitle按钮文字(可为空) popover气泡框title(可为空)columnsData所有的完整的表格头部信息(不可为空)colorsData(用来排序的数组 可为空)-->
		<Drag butTitle="点击排序"  popover='表格排序' :columnsData='columnsAll' :colorsData='colors' @onChange='setColumns'></Drag>
	
<div style="margin-top: 200px;">
	<a-table :columns="columns" :dataSource="data" bordered>
		<template v-for="col in ['name', 'age', 'address']" :slot="col" slot-scope="text, record, index">
			<div :key="col">
				<a-input v-if="record.editable" style="margin: -5px 0" :value="text" @change="e => handleChange(e.target.value, record.key, col)" />
				<template v-else>{{text}}</template>
			</div>
		</template>
		<template slot="operation" slot-scope="text, record, index">
			<div class='editable-row-operations'>
				<span v-if="record.editable">
					<a @click="() => save(record.key)">Save</a>
					<a-popconfirm title='Sure to cancel?' @confirm="() => cancel(record.key)">
						<a>Cancel</a>
					</a-popconfirm>
				</span>
				<span v-else>
					<a @click="() => edit(record.key)">Edit</a>
				</span>
			</div>
		</template>
	</a-table>
</div>
		


	</div>






</template>
<script>
	
	import Drag from '@/components/drag'  //引入drag组件
	
	const data = []
	for (let i = 0; i < 100; i++) {
		data.push({
			key: i.toString(),
			name: `Edrward ${i}`,
			age: 32,
			address: `London Park no. ${i}`,
		})
	}

	export default {
		
		components:{
			Drag,
		},
		
		data() {
			return {

				data,  //data 为表格数据
				columnsAll: [{  //columnsAll为该表单中所有的头部数据
					title: 'name',
					dataIndex: 'name',
					width: '25%',
					scopedSlots: {
						customRender: 'name'
					},
				}, {
					title: 'age',
					dataIndex: 'age',
					width: '15%',
					scopedSlots: {
						customRender: 'age'
					},
				}, {
					title: 'address',
					dataIndex: 'address',
					width: '40%',
					scopedSlots: {
						customRender: 'address'
					},
				}, {
					title: 'operation',
					dataIndex: 'operation',
					scopedSlots: {
						customRender: 'operation'
					},
				}],
		
				columns:[], //表格最终要展示的头部信息
				
				
				colors:[{   // colors数组的想法是基于从数据库中取要展示的头部信息
					'text':'name',
					'key':'name',
					'checked':true
					
				},
				
				{
					'text':'age',
					'key':'age',
					'checked':true
				},
				
				{
					'text':'address',
					'key':'address',
					'checked':false
				},
				{
					'text':'operation',
					'key':'operation',
					'checked':true
				}
				
				],
	

			}
		},
		methods: {
			

			setColumns:function  (val) {  //drag组件 改变时回调该方法 回调回来的val 是表格最终的头部信息
				this.columns=val
			},

//以下是ant table方法

handleChange(value, key, column) {
				const newData = [...this.data]
				const target = newData.filter(item => key === item.key)[0]
				if (target) {
					target[column] = value
					this.data = newData
				}
			},
			edit(key) {
				const newData = [...this.data]
				const target = newData.filter(item => key === item.key)[0]
				if (target) {
					target.editable = true
					this.data = newData
				}
			},
			save(key) {
				const newData = [...this.data]
				const target = newData.filter(item => key === item.key)[0]
				if (target) {
					delete target.editable
					this.data = newData
					this.cacheData = newData.map(item => ({ ...item
					}))
				}
			},
			cancel(key) {
				const newData = [...this.data]
				const target = newData.filter(item => key === item.key)[0]
				if (target) {
					Object.assign(target, this.cacheData.filter(item => key === item.key)[0])
					delete target.editable
					this.data = newData
				}
			},
		

		},
		mounted() {
		
		}
	}
</script>

5.最终效果

 

6.该功能是基于awe-dnd插件和ant design 开发完成 ,以上drag组件也可使用于其他vue框架 如iview ,使用其他框架要遵循框架具体使用情况,需要保证drag组件绑定的onChange事件触发的回调函数中返回的数据val 适用于其余框架的table规范。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值