需要实现表格列宽度调整,选择展示表格字段,以及显示顺序,先看效果,每次变动后保存到本地缓存中,也可以与后台配合保存到数据库,实现用户自定义表格.
1.安装vuedraggable实现拖拽
npm i vuedraggable
2.新建组件 FilterColumns.vue
我这里默认把操作列放到最后一个并且不允许编辑,如不需要可删除
<template><RadioGroup type="button"><Radio title="筛选列"><Icon type="md-list" class="showColumn" @click="modalVisible = true"></Icon><Modaltitle="筛选列"v-model="modalVisible":mask-closable="false":width="800"><Form ref="form" inline><FormItem style="width: 98%" class="showcolumns"><CheckboxGroup v-model="selectTitles" @on-change="changeColumns"><draggablev-model="sortTitles"chosenClass="active"animation="500"@end="changeColumns"><Checkboxv-for="(item, index) in sortTitles":key="index":label="item"v-show="!['操作', 'undefined'].includes(item + '')"><span>{{ item }}</span></Checkbox></draggable></CheckboxGroup></FormItem></Form><div slot="footer"><Button type="text" @click="clear">重置</Button><Button type="text" @click="modalVisible = false">取消</Button><Button type="success" @click="reverseSelect">反选</Button></div></Modal></Radio></RadioGroup>
</template><script>
import draggable from "vuedraggable";
export default {name: "FilterColumns",components: { draggable },props: {columns: {type: Array,default: () => [],},cacheKey: {type: String,default: "",},},data() {return {key: "",modalVisible: false, // 添加或编辑显示selectTitles: [],sortTitles: [],widthTitles:{init:"0",},};},methods: {changeColumnsWidth(v){if(v){this.widthTitles[v[2].title] = v[0];this.changeColumns();}},clear(){this.removeStore(`select::${this.key}`);this.removeStore(`sort::${this.key}`);this.removeStore(`width::${this.key}`);this.init();},init() {//this.key = this.$route.name;if (this.cacheKey) {this.key = this.cacheKey;} else {this.key = this.$route.name;}this.initData();this.changeColumns();},initData() {//此处保存到本地缓存,可换成请求后台接口获取用户自定义数据let selectTitleStr = this.getStore(`select::${this.key}`);this.selectTitles = selectTitleStr && selectTitleStr != "[]"? JSON.parse(selectTitleStr) : [];let sortColumsStr = this.getStore(`sort::${this.key}`);this.sortTitles =sortColumsStr && sortColumsStr != "[]" ? JSON.parse(sortColumsStr) : [];let widthColumsStr = this.getStore(`width::${this.key}`);this.widthTitles =widthColumsStr && widthColumsStr != "{}" ? JSON.parse(widthColumsStr) : { init:"0"};},changeColumns() {var that = this;if (!!!this.sortTitles.length) {this.sortTitles = this.columns.map((item) => item.title).filter((item) => item && item.title != "操作");}this.columns.forEach(item => {item.resizable = true;if(!item.width && item.minWidth){item.width = item.minWidth} else if(!item.width && !item.minWidth){item.width = 200;}});if (this.widthTitles.init=="0") {this.columns.forEach(item=>{that.widthTitles[item.title] = item.width;})that.widthTitles.init = "1";}//如果选中标题不存在则赋予全部if (!!!this.selectTitles.length) {this.selectTitles = JSON.parse(JSON.stringify(this.sortTitles));}//此处保存到本地缓存,可换成请求后台接口,保存至数据库this.setStore(`select::${this.key}`, JSON.stringify(this.selectTitles));this.setStore(`sort::${this.key}`, JSON.stringify(this.sortTitles));this.setStore(`width::${this.key}`, JSON.stringify(this.widthTitles));let currentColumns = this.columns.filter((item) =>this.selectTitles.includes(item.title) ||!!!item.title ||item.title == "操作").map((item, index) => {if (item.title !== "操作" && item.title) {item.titleSort = this.sortTitles.findIndex((sortTitle) => item.title == sortTitle);} else if (item.title == "操作") {item.titleSort = this.sortTitles.length;} else {item.titleSort = -this.sortTitles.length + index;}return item;});currentColumns.sort((a, b) => a.titleSort - b.titleSort);currentColumns.forEach(item=>{item.width = that.widthTitles[item.title];})delete currentColumns[currentColumns.length-1].widthcurrentColumns[currentColumns.length-1].minWidth= 162;this.$emit("on-change", currentColumns);},reverseSelect() {if (this.selectTitles.length > 0) {this.selectTitles = [];} else {this.selectTitles = JSON.parse(JSON.stringify(this.sortTitles));this.changeColumns();}},},mounted() {this.init();this.$nextTick(function() {this.$on('changeCWidth', function(newWidth, oldWidth, column, event) {this.changeColumnsWidth(newWidth, oldWidth, column, event);});});},
};
</script>
<style lang="less" scoped>
.filter-columns-btn {width: 30px;height: 30px;line-height: 25px;text-align: center;border-radius: 2px;border: 1px solid #4383f3;cursor: pointer;
}
</style>
3.在main.js中注册成全局组件
import FilterColumns from '@/views/my-components/FilterColumns'
Vue.component('filterColumns', FilterColumns);
4.使用方法
在合适位置(一般搜索按钮后,会显示筛选按钮)引入组件
<filterColumnsref="fc":columns="columns"@on-change="currentColumns = $event"/><Table@on-column-width-resize="$refs.fc.changeColumnsWidth(arguments)":columns="currentColumns":data="data"ref="table"></Table><script>
export default {data() {//可展示的字段columns:[{type: "selection",width: 35,align: "center",},{type: "index",width: 55,align: "center",},],//需要展示的字段,设置为空数组即可currentColumns:[],}
}
</script>