• 【Vue】如何写一个表格列显隐控制的组件?


    需求

    公司项目需要实现对表格列的显示隐藏进行配置,额外配置可自行添加,感觉这个组件挺泛用的,随便记录下。

    这里只是说简单的显隐控制,复杂的只是在页面里面多写而已,核心代码是一样的。

    简单的:

    image

    比较复杂的:

    image

    代码实现

    表格页面.vue

    <column-setup
    @columnSetup="columnSetup"
    :baseSelectedColumns="selectedColumns"
    page="report"
    ></column-setup>
    					
    <el-table-column
    prop="name"
    label="Name"
    width="auto"
    v-if="isShowClumn('Name')"
    show-overflow-tooltip
    ></el-table-column>
    
          selectedColumns: [
            {
              displayName: 'Name',
              show: true,
            },
            {
              displayName: 'Email Address',
              show: true,
            },
            {
              displayName: 'Profile Type',
              show: true,
            },
            {
              displayName: 'User Type',
              show: true,
            },
          ],
    
        columnSetup(selectedColumns) {
          this.selectedColumns = selectedColumns
        },
        isShowClumn(name) {
          let isShow
          this.selectedColumns.forEach((item) => {
            if (item.displayName === name) {
              isShow = item.show
            }
          })
          return isShow
        },
    

    组件.vue

    样式请自行删减,有些是无用代码。

    点击查看代码
    <template>
      <div class="table-custom-display">
        <el-tooltip effect="dark" content="Columns" placement="top">
          <el-popover
            placement="bottom"
            title=""
            trigger="click"
            v-model="visible"
            popper-class="columns-popover"
            @hide="close()"
            @show="show"
          >
            <h2>Columns</h2>
            <div class="top-check">
              <el-input
                placeholder="Search"
                prefix-icon="el-icon-search"
                v-model.trim="selectParam"
                clearable
                size="mini"
                @input="search"
              ></el-input>
              <div class="bot-check">
                <template v-for="(item, index) in selectedColumns">
                  <div :key="item.name">
                    <el-checkbox
                      v-model="item.show"
                      :key="item.name"
                      checked
                      v-show="isShowItem(item, index)"
                    >
                      <div class="switch-defaults-name">
                        {{ item.displayName }}
                      </div>
                    </el-checkbox>
                  </div>
                </template>
              </div>
            </div>
            <div style="text-align: right; margin: 0" class="footer">
              <el-button type="primary" size="mini" @click="done">
                Done
              </el-button>
              <el-button size="mini" type="text" @click="visible = false">
                Cancel
              </el-button>
            </div>
            <el-button
              type=""
              size="medium"
              icon="el-icon-setting"
              style="font-size: 14px; margin-left: 10px; margin-top: 15px;"
              slot="reference"
            ></el-button>
          </el-popover>
        </el-tooltip>
      </div>
    </template>
    
    <script>
    export default {
      name: '',
      props: {
        baseSelectedColumns: {
          type: Array,
          default: () => {
            return []
          },
        },
      },
      data() {
        return {
          buttons: sessionStorage.getItem('buttonPermissions'),
          visible: false,
          selectParam: '',
          matchIndexArr: [],
          initSelectedColumns:[],
          selectedColumns: [],
        }
      },
      watch: {
        baseSelectedColumns: {
          deep: true, // 深度监听
          handler(newVal, oldVal) {
            this.selectedColumns = JSON.parse(JSON.stringify(newVal))
          },
        },
      },
      mounted(){
        this.selectedColumns = JSON.parse(JSON.stringify(this.baseSelectedColumns))
      },
      methods: {
        close() {
          this.visible = false
        },
        show(){
          this.selectedColumns = JSON.parse(JSON.stringify(this.baseSelectedColumns))
        },
        done() {
          let content = JSON.parse(JSON.stringify(this.selectedColumns))
          this.visible = false
          this.$emit('columnSetup', content)
        },
        search() {
          this.matchIndexArr = []
          this.selectedColumns.forEach((item, index) => {
            let str = item.displayName.toLowerCase()
            if (str.match(this.selectParam) !== null) {
              this.matchIndexArr.push(index)
            }
          })
        },
        isShowItem(item, index) {
          if (this.selectParam) {
            return this.matchIndexArr.indexOf(index) !== -1
          } else {
            return true
          }
        },
      },
    }
    </script>
    
    <style scoped lang="scss">
    ::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
      color: #596571 !important;
    }
    
    ::v-deep .el-checkbox {
      display: flex;
      margin-right: 0;
    }
    
    ::v-deep .el-checkbox__input,
    .is-checked {
      display: flex;
      align-items: center;
    }
    
    ::v-deep .el-checkbox__label {
      /* background-color: red; */
       98%;
      height: 30px;
    }
    
    ::v-deep .el-switch.is-checked .el-switch__core {
      border-color: #47bfaf !important;
      background-color: #47bfaf !important;
    }
    
    .top-check {
      // display: flex;
      // align-content: center;
      // justify-content: space-between;
    
      .reset {
        cursor: pointer;
        font-size: 14px;
      }
    
      /deep/.el-tabs__item {
        height: 28px;
        line-height: 28px;
        font-size: 18px;
        padding: 0 20px !important;
        color: #828282;
      }
    
      /deep/ .el-tabs__item:hover {
        color: #828282 !important;
      }
    
      /deep/ .el-tabs__item.is-active {
        color: #47bfaf !important;
      }
    
      /deep/ .el-input__inner {
        border: 1px solid #1e384b !important;
        color: #1e384b !important;
        border-radius: 5px;
        font-weight: 500;
        height: 35px;
      }
    
      /deep/ .el-icon-circle-close {
        color: #828282 !important;
        margin-left: -20px;
        line-height: 28px;
      }
    }
    
    .bot-check {
      margin-top: 10px;
      height: 170px;
      overflow-y: auto;
    
      /deep/.el-checkbox__label {
        padding: 5px 10px;
      }
    
      /deep/.el-link--inner {
        padding: 10px 0;
      }
    
      .check-box {
        display: flex;
        flex-direction: column;
      }
    
      .system-check-box {
        display: flex;
        justify-content: space-between;
      }
    
      .switch-defaults-name {
        max- 223px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
    
      .switch-system-name {
        max- 183px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
    
      .label-wrapper {
        margin: 14px 0;
        display: flex;
    
        &:nth-child(2) {
          margin-top: 0;
        }
    
        .label-item {
          display: flex;
          align-items: center;
        }
    
        .label-text {
          margin-left: 10px;
        }
    
        .label-switch {
          flex-grow: 1;
          justify-content: right;
        }
      }
    }
    
    .footer {
      /deep/ .el-button--primary {
        border-radius: 5px !important;
        background-color: #47bfaf;
        border-color: #47bfaf;
      }
    }
    
    .table-custom-display {
    }
    </style>
    <style>
    .columns-popover {
      background-color: #fff;
       300px;
    }
    
    .icon-popover {
      background: #fff;
    }
    
    .columns-tootip {
      z-index: 200000000000020 !important;
    }
    
    .switch-tootip .popper__arrow {
      left: 40px !important;
    }
    </style>
    
    
  • 相关阅读:
    数据结构——线性结构(链表)
    栈和队列的应用——迷宫问题(深度、广度优先搜索)
    数据结构——线性结构(列表、栈、队列)
    hibernate之HQL
    hibernate关联关系(多对多)
    Hibernate关联关系(一对多)
    hibernate之主键生成策略
    hibernate入门
    reduce个数问题
    hbase连接linux开发过程
  • 原文地址:https://www.cnblogs.com/cqkjxxxx/p/16301012.html
Copyright © 2020-2023  润新知