表头拖拽排序应用的是不同人员对数据关注点不一样,表格太长,可以把主要关注的列拖拽排序到前面,方便查看。
然后把当前用户,当前页面的排序记录在本地缓存,这样用户在下次登陆仍然能够使用自己的排序。
拖拽用的是vuedraggable
是标准的组件式封装,并且将可拖动元素放进了 transition-group
上面,过渡动画都比较好。
html 页面
打开拖拽按钮
<el-button circle size="small" @click="handleOpen" icon="el-icon-sort"></el-button>
拖拽组件
<sort-header :dialogShow="sortHeaderDialogShow" :columnList="currentOptionColumns" @beforeClose="sortHeaderDialogClose" @handSubmit="handSortByCacheSubmit" ></sort-header>
因为所有的页面都要使用这个拖拽排序,所以把方法集中在mixins里面,方便调用。
下面是mixins页面
import {deepClone} from "@/util/util"; export default { data(){ return { //列排序 sortHeaderDialogShow: false, defaultOption: 'option', currentOptionColumns: [], //导出excel exportExcelShow:false, } }, created() { //初始化 this.currentOptionColumns = this[this.defaultOption].column; }, mounted(){ this.getSortByCache(); }, watch: { 'defaultOption'(val) { if (val) { //监听,当前的option名称变动时刷新当前的列 this.currentOptionColumns = this[this.defaultOption].column; } } }, methods:{ /** * 打开排序弹窗 */ handleOpen(){ this.sortHeaderDialogShow = true }, /** * 获取排序缓存 */ getSortByCache() { let currentUrl = this.$router.history.current.fullPath let saveAccount = JSON.parse(localStorage.getItem("saber-userInfo")).content.account let defaultOption = this.defaultOption; let cache = localStorage.getItem(`${currentUrl}-${defaultOption}_${saveAccount}`) if(cache) { let columns = JSON.parse(cache); //重排序并进行覆盖 let list = this.againSort(this.option.column, columns); // debugger this[this.defaultOption].column = list; } }, /** * 关闭弹窗方法 * 通过修改子的变量进行修改 * 组件会向下传递关闭父弹窗 */ sortHeaderDialogClose() { this.sortHeaderDialogShow = false }, /** * 弹窗确认提交 * 对列进行重排序 * 修改当前页面对应的排序组件 * @param columns 重排序的列数组 */ handSortByCacheSubmit(columns) { let currentUrl = this.$router.history.current.fullPath let saveAccount = JSON.parse(localStorage.getItem("saber-userInfo")).content.account let defaultOption = this.defaultOption; localStorage.setItem(`${currentUrl}-${defaultOption}_${saveAccount}`,JSON.stringify(columns)) let list = this.againSort(this[this.defaultOption].column, columns); // debugger this[this.defaultOption].column = list; this.sortHeaderDialogClose(); }, /** * 重新排序 */ againSort(optionColumn, columns) { let tempColumn = deepClone(optionColumn); let list = []; columns.forEach(item =>{ for (let i = 0; i < tempColumn.length; i++) { let c = tempColumn[i]; if(c.prop == item.key) { list.push(c); //移除 tempColumn.splice(i, 1); break; } } }) //把不存在的加入到集合的最后面 list.push(... tempColumn); return list; } } }
组件详情
<template> <el-dialog title="列排序" :visible.sync="dialogShow" :close-on-click-modal="false" width="60%" append-to-body @open="initCloumn" :before-close="handClose"> <div class="box scrollbar-5"> <draggable style="display: flex;flex-wrap: wrap;" id="myArray" v-model="column" animation="150"> <!--固定排序的跟隐藏的不列出来--> <div class="tag" v-for="item in column" :key="item.key" v-if="item.fixed !=true && item.hide != true"> {{item.value}} </div> </draggable> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="handSubmit">确 定</el-button> <el-button @click="handClose">取 消</el-button> </span> </el-dialog> </template> <script> import draggable from "vuedraggable" export default { components: { draggable }, props: { /** * 弹窗 */ dialogShow: { type: Boolean, default: false }, columnList: { type: Array, default: () => {return []} } }, data() { return { column: [] }; }, methods: { initCloumn() { this.column = []; this.columnList.forEach(res =>{ this.column.push({ fixed:res.fixed, hide:res.hide, key: res.prop, value: res.label }) }) }, handSubmit() { this.$emit('handSubmit', this.column) }, handClose() { this.$emit('beforeClose', this.column) } }, }; </script> <style scoped> .tag{ padding: 5px 10px; border: 1px solid #c0c4cf; border-radius: 9px; margin: 5px; cursor:pointer; } </style>