当前位置:   article > 正文

ElementUI实现el-table列的显示与隐藏和列拖拽(RuoYi分离版)_el-table right-toolbar

el-table right-toolbar

显示隐藏步骤思路:

一、table要实现v-for循环添加列的操作

二、给列添加v-if属性 方法返回当前列是否显示隐藏

①在RightToolBar添加列显示隐藏的图标控件                                                                                    

  1. <template>
  2. <div class="top-right-btn">
  3. <el-row>
  4. <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top">
  5. <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
  6. </el-tooltip>
  7. <el-tooltip class="item" effect="dark" content="刷新" placement="top">
  8. <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
  9. </el-tooltip>
  10. <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns!=undefined">
  11. <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px">
  12. <el-button size="mini" circle icon="el-icon-menu"/>
  13. <el-dropdown-menu slot="dropdown">
  14. <template v-for="item in columns">
  15. <el-dropdown-item><el-checkbox :checked="item.isShow" @change="monitorChange($event,item.label)" :label="item.label"></el-checkbox></el-dropdown-item>
  16. </template>
  17. </el-dropdown-menu>
  18. </el-dropdown>
  19. </el-tooltip>
  20. </el-row>
  21. <el-dialog :title="title" :visible.sync="open" append-to-body>
  22. <el-transfer
  23. :titles="['显示', '隐藏']"
  24. v-model="value"
  25. :data="columns"
  26. @change="dataChange"
  27. ></el-transfer>
  28. </el-dialog>
  29. </div>
  30. </template>
  31. <script>
  32. export default {
  33. name: "RightToolbar",
  34. data() {
  35. return {
  36. // 显隐数据
  37. value: [],
  38. // 弹出层标题
  39. title: "显示/隐藏",
  40. // 是否显示弹出层
  41. open: false,
  42. };
  43. },
  44. props: {
  45. showSearch: {
  46. type: Boolean,
  47. default: true,
  48. },
  49. columns: {
  50. type: Array,
  51. },
  52. },
  53. created() {
  54. },
  55. methods: {
  56. // 搜索
  57. toggleSearch() {
  58. this.$emit("update:showSearch", !this.showSearch);
  59. },
  60. // 刷新
  61. refresh() {
  62. this.$emit("queryTable");
  63. },
  64. // 右侧列表元素变化
  65. dataChange(data) {
  66. for (var item in this.columns) {
  67. const key = this.columns[item].key;
  68. this.columns[item].visible = !data.includes(key);
  69. }
  70. },
  71. monitorChange(event,label){
  72. this.columns.filter(item=>item.label==label)[0].isShow=event
  73. }
  74. },
  75. };
  76. </script>
  77. <style lang="scss" scoped>
  78. ::v-deep .el-transfer__button {
  79. border-radius: 50%;
  80. padding: 12px;
  81. display: block;
  82. margin-left: 0px;
  83. }
  84. ::v-deep .el-transfer__button:first-child {
  85. margin-bottom: 10px;
  86. }
  87. </style>

 下列菜单用的是checkBox组 成品效果就是这样的

                                ​​​​​​​        ​​​​​​​        ​​​​​​​        

具体两个父子控件怎么传递数据,这里不过多讲解。

下面是表格的主要代码

  1. <right-toolbar
  2. :showSearch.sync="showSearch"
  3. :columns="allTableLabel"
  4. @queryTable="getList"
  5. ></right-toolbar>
  6. </el-row>
  7. <el-table
  8. v-loading="loading"
  9. :data="purchaseList"
  10. row-key="id"
  11. border
  12. ref="purchaseTable"
  13. @selection-change="handleSelectionChange"
  14. >
  15. <template
  16. v-for="column in tableColumns">
  17. <el-table-column
  18. v-if="judgeIsShow(column.label)"
  19. :key="column.id"
  20. :prop="column.prop"
  21. :class-name="column.isDrag"
  22. :label="column.label"
  23. :align="column.align"
  24. :type="column.type"
  25. :width="column.width"
  26. >
  27. <template v-if="column.scope=='scope'" scope="scope">
  28. <span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
  29. </template>
  30. <template v-else-if="column.scope=='slot-scope'" slot-scope="scope">
  31. {{scope.row.contractNum}}/{{getUnit(scope.row.quantityUnit)}}
  32. </template>
  33. <template v-else-if="column.scope=='ClientTag'" slot-scope="scope">
  34. <ClientTag :value="scope.row.contractId" :flag="flag" :view="table"/>
  35. </template>
  36. </el-table-column>
  37. </template>
  38. </el-table>

下边的定义的数据和方法的代码

  1. //elementui测试
  2. tableColumns:[
  3. {id:"0",type:"selection",width:"55",align:"center"},
  4. {id:"1",type:"index",label:"序号",align:"center",scope:"scope"},
  5. {id:"2",label:"采购合同号",prop:"contractNo",align:"center",isDrag:"drag"},
  6. {id:"3",label:"原产国",prop:"countryName",align:"center",isDrag:"drag"},
  7. {id:"4",label:"产品",prop:"productName",align:"center",isDrag:"drag",scope:"ClientTag"},
  8. {id:"5",label:"合同总数量",prop:"contractNum,quantityUnit",isDrag:"drag",align:"center",scope: "slot-scope"},
  9. {id:"6",label:"合同总金额",prop:"contractPrice",align:"center"},
  10. ],
  11. //elementui的table所有的表头数据
  12. allTableLabel:[],
  13. //把列的显示和隐藏 存Cookie
  14. setTableShowToCookie(){
  15. let label="";
  16. let isShow="";
  17. let labelArr=[];
  18. let isShowArr=[];
  19. this.allTableLabel.forEach((item)=>{
  20. labelArr.push(item.label)
  21. isShowArr.push(item.isShow);
  22. })
  23. label=labelArr.join(',')
  24. isShow=isShowArr.join(',')
  25. Cookies.set("purchaseTableLabel",label)
  26. Cookies.set("purchaseTableIsShow",isShow)
  27. },
  28. getTableShowOfCookie(){
  29. let label=Cookies.get("purchaseTableLabel");
  30. let isShow=Cookies.get("purchaseTableIsShow");
  31. console.log(label)
  32. if (label==undefined){
  33. this.allTableLabel=[
  34. {label:"序号",isShow:true},
  35. {label:"采购合同号",isShow:true},
  36. {label:"原产国",isShow:true},
  37. {label:"产品",isShow:true},
  38. {label:"合同总数量",isShow:true},
  39. {label:"合同总金额",isShow:true},
  40. ];
  41. }else{
  42. let labelArr=label.split(",");
  43. let isShowArr=isShow.split(",");
  44. let len=labelArr.length;
  45. console.log("长度为"+len)
  46. for (let i=0;i<len;i++){
  47. this.allTableLabel.push({label:labelArr[i],isShow:isShowArr[i]=="true"?true:false});
  48. }
  49. }
  50. },
  51. //判断是否显示列
  52. judgeIsShow(column){
  53. let exist=this.allTableLabel.filter(item=> item.label==column);
  54. let isShow;
  55. if (exist.length==0){
  56. isShow=true
  57. }else{
  58. isShow= exist[0].isShow;
  59. }
  60. return isShow;
  61. },

 主要逻辑就是通过改变checkBox的选中和取消同步列的显示和隐藏  这个地方是根据两个数组中的label属性进行判断的  两者的label的值要保持一致。

效果图如下:

列拖拽的步骤思路:

        一、要借助第三方插件Sortable.js

        二、主要是改变table遍历的列的顺序

  1. <el-table
  2. v-loading="loading"
  3. :data="purchaseList"
  4. row-key="id"
  5. border
  6. ref="purchaseTable"
  7. @selection-change="handleSelectionChange"
  8. >
  9. <template
  10. v-for="column in tableColumns">
  11. <el-table-column
  12. v-if="judgeIsShow(column.label)"
  13. :key="column.id"
  14. :prop="column.prop"
  15. :class-name="column.isDrag"
  16. :label="column.label"
  17. :align="column.align"
  18. :type="column.type"
  19. :width="column.width"
  20. >
  21. <template v-if="column.scope=='scope'" scope="scope">
  22. <span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
  23. </template>
  24. <template v-else-if="column.scope=='slot-scope'" slot-scope="scope">
  25. {{scope.row.contractNum}}/{{getUnit(scope.row.quantityUnit)}}
  26. </template>
  27. <template v-else-if="column.scope=='ClientTag'" slot-scope="scope">
  28. <ClientTag :value="scope.row.contractId" :flag="flag" :view="table"/>
  29. </template>
  30. </el-table-column>
  31. </template>
  32. </el-table>
  33. import Sortable from "sortablejs";
  34. import draggable from "vuedraggable";
  35. export default {
  36. name: "Purchase",
  37. components: {
  38. draggable,
  39. Sortable,
  40. },
  41. data() {
  42. return {
  43. table:"productTable",
  44. flag:"contractProducts",
  45. //elementui测试
  46. tableColumns:[
  47. {id:"0",type:"selection",width:"55",align:"center"},
  48. {id:"1",type:"index",label:"序号",align:"center",scope:"scope"},
  49. {id:"2",label:"采购合同号",prop:"contractNo",align:"center",isDrag:"drag"},
  50. {id:"3",label:"原产国",prop:"countryName",align:"center",isDrag:"drag"},
  51. {id:"4",label:"产品",prop:"productName",align:"center",isDrag:"drag",scope:"ClientTag"},
  52. {id:"5",label:"合同总数量",prop:"contractNum,quantityUnit",isDrag:"drag",align:"center",scope: "slot-scope"},
  53. {id:"6",label:"合同总金额",prop:"contractPrice",align:"center"},
  54. ],
  55. //elementui的table所有的表头数据
  56. allTableLabel:[],
  57. mounted() {
  58. this.columnDrop();
  59. },
  60. methods: {
  61. //列拖拽
  62. columnDrop(){
  63. //const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
  64. const wrapperTr = this.$refs.purchaseTable.$el.querySelector('.el-table__header-wrapper tr');
  65. const that=this;
  66. this.sortable = Sortable.create(wrapperTr, {
  67. animation: 180,
  68. delay: 30,
  69. draggable:".drag",
  70. onEnd: evt => {
  71. if (this.tableColumns[evt.newIndex].isDrag!=undefined) {
  72. const oldItem = this.tableColumns[evt.oldIndex]
  73. this.tableColumns.splice(evt.oldIndex, 1);
  74. this.tableColumns.splice(evt.newIndex, 0, oldItem)
  75. //改变两个列的id属性之后 表格的数据才进行跟新
  76. this.tableColumns[evt.oldIndex].id=parseTime(new Date(), "{y}{m}{d}{h}{i}{s}")+"1"
  77. this.tableColumns[evt.newIndex].id=parseTime(new Date(), "{y}{m}{d}{h}{i}{s}")+"2"
  78. }else{
  79. }
  80. },
  81. });
  82. },
  83. }

 效果图如下显示:

到此为止分别引用的时候是没问题的。

但是两者整合的时候有BUG

主要原因是因为拖拽的是显示的列,而重排的是全部的列,同时evt.oldIndex和evt.newIndex是显示列拖拽的column的index  这个地方用splice方法重排所有的column的index  排序的时候就出现乱排、不排的现象。

解决思路:

获得拖拽列的两个列的label  然后遍历全部的列  要是label相等的就返回全部列其中两个相等label列的下标  然后重排这两个列就行。

具体代码优化如下:

  1. //列拖拽
  2. columnDrop(){
  3. //const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
  4. const wrapperTr = this.$refs.purchaseTable.$el.querySelector('.el-table__header-wrapper tr');
  5. const tableColumn=this.$refs.purchaseTable.columns;
  6. let oldLabel;
  7. let newLabel;
  8. let oldIndex;
  9. let newIndex;
  10. let count=0;
  11. const that=this;
  12. this.sortable = Sortable.create(wrapperTr, {
  13. animation: 180,
  14. delay: 30,
  15. draggable:".drag",
  16. onEnd: evt => {
  17. if (this.tableColumns[evt.newIndex].isDrag!=undefined) {
  18. oldLabel=this.$refs.purchaseTable.columns[evt.oldIndex].label;
  19. newLabel=this.$refs.purchaseTable.columns[evt.newIndex].label;
  20. for (let i=0;i<that.tableColumns.length;i++){
  21. if (that.tableColumns[i].label!=undefined&&that.tableColumns[i].label==newLabel)
  22. newIndex=i;
  23. };
  24. for (let i=0;i<that.tableColumns.length;i++){
  25. if (that.tableColumns[i].label!=undefined&&that.tableColumns[i].label==oldLabel)
  26. oldIndex=i;
  27. }
  28. const oldItem = this.tableColumns[oldIndex]
  29. this.tableColumns.splice(oldIndex, 1);
  30. this.tableColumns.splice(newIndex, 0, oldItem)
  31. this.tableColumns.forEach((item)=>{
  32. if(item.label==newLabel||item.label==oldLabel){
  33. item.id=parseTime(new Date(), "{y}{m}{d}{h}{i}{s}") + (++count)
  34. console.log(item.label)
  35. }
  36. })
  37. }else{
  38. }
  39. },
  40. });
  41. },

整体效果图如下:

 

以上代码只是粘贴了主要部分,有什么好的方法欢迎交流

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/420188
推荐阅读
相关标签
  

闽ICP备14008679号