需要實現表格列寬度調整,選擇展示表格字段,以及顯示順序,先看效果,每次變動后保存到本地緩存中,也可以與后臺配合保存到數據庫,實現用戶自定義表格.
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>