• 基于vue+Element Table Popover 弹出框内置表格的封装


    项目场景:

    在选择数据的时候需要在已选择的数据中对比选择,具体就是点击一个按钮,弹出一个小的弹出框,但不像对话框那样还需要增加一个遮罩层,更加的轻量化,但是需要查看的数据很多需要一个列表来展示,列表的话还需要一个筛选功能。

    我的思路是增加复选框列,将选择的内容插入到外部的列表中,我这里主要是分享弹出框内置列表的一个封装思路。
    但是在这当中还会设计到列表、分页的方法,所以建议先搞清楚列表以及分页在来看,这些我之前的文章都有涉及。


    实现效果

    在这里插入图片描述

    认识组件

    老样子先根据Element的官方文档认识一下Popover 弹出框

    代码

    <el-popover
      placement="right"
      width="400"
      trigger="click">
      <el-table :data="gridData">
        <el-table-column width="150" property="date" label="日期"></el-table-column>
        <el-table-column width="100" property="name" label="姓名"></el-table-column>
        <el-table-column width="300" property="address" label="地址"></el-table-column>
      </el-table>
      <el-button slot="reference">click 激活</el-button>
    </el-popover>
    
    <script>
      export default {
        data() {
          return {
            gridData: [{
              date: '2016-05-02',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄'
            }, {
              date: '2016-05-04',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄'
            }, {
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄'
            }, {
              date: '2016-05-03',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄'
            }]
          };
        }
      };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    效果

    在这里插入图片描述

    分析

    这个是一个基础的Popover 弹出框,在这当中我们要用到的方法、函数有:

    • placement:出现位置 :top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end
    • width:弹出框宽度:800 (最小宽度 150px)
    • popper-class:为 popper 添加类名:popover
    • show:显示时触发:handlePopoverShow
    • v-model:状态是否可见:visible
    • trigger:触发方式:click/focus/hover/manual

    这些就是在Popover 弹出框中要用到的内置方法及函数


    封装:

    代码

    <!-- 
    
      component:Popover弹出框(内置列表)
      time:2023/08/10
    
      placement:位置
      popoverText:按钮文字
      popoverIcon:按钮图表
      tableType:MultipleChoice(单选)、CheckBox(多选)
      tableData:列表数据
      tableConfig:列表配置
      loading:开启列表加载
      totalNum:分页总数
      width:宽度
      handlePopoverShow:弹出框显示触发
      handleSizeChange:分页条数
      handleCurrentChange:分页页数
      handleSelectData:确定触发事件
    
    -->
    <template>
      <div class="popover">
        <el-popover
          :placement="placement"
          :width="width"
          popper-class="popover"
          @show="handlePopoverShow"
          v-model="visible"
          trigger="click">
          <el-form ref="PopoverQuery" label-width="80px" class="PopoverQuery">
            <el-card shadow="hover">
              <el-form-item :label="$t('query_condition')" class="PopoverQuery-FormItem">
                <el-input class="PopoverQuery-Input" :placeholder="placeholder"></el-input>
                <el-button size="mini" icon="el-icon-search">{{$t('Query')}}</el-button>
              </el-form-item>
            </el-card>
          </el-form>
          <Table ref="table" :total="totalNum" @handleSizeChange="handleSizeChange" @handleCurrentChange="handleCurrentChange" :loading="loading" :tableData="tableData" :tableConfig="tableConfig" :tableType="tableType" @RowClick="tableRowClick" @HandleSelectionChange="selectionChange"></Table>
          <div class="mar-top-10" style="overflow: hidden;">
            <!-- 单选清空 -->
            <el-button size="mini" class="FloatRight" icon='el-icon-refresh' @click="EmptyTableSelectStatus('MultipleChoice')" v-if="tableType=='MultipleChoice'">{{ $t('empty') }}</el-button>
            <!-- 多选清空 -->
            <el-button size="mini" class="FloatRight" icon='el-icon-circle-close' @click="cancel('CheckBox')" v-else>{{ $t('Cancel') }}</el-button>
            <el-button size="mini" type="success" class="card-title-button"  @click="handleSelectData" style="margin-right:10px" icon='el-icon-circle-check'>{{ $t('determine') }}</el-button>
          </div>
          <el-button size="mini" class="card-title-button" :icon='popoverIcon' slot="reference">{{ popoverText }}</el-button>
        </el-popover>
      </div>
      
    </template>
    
    <script>
    import Table from '@/components/table/index.vue'
    export default {
      components:{Table},
      data() {
        return {
          visible:false, 
          selectData:[] //复选框选择的数据
        };
      },
      props:{
        popoverText:{
          default(){
            return [];
          }
        },
        popoverIcon:{
          default(){
            return [];
          }
        },
        tableData:{
          default(){
            return [];
          }
        },
        tableConfig:{
          default(){
            return [];
          }
        },
        tableType:{
          default(){
            return [];
          }
        },
        loading:{
          type:Boolean,
          default: false
        },
        width:{
          type:String,
          default:'500',
        },
        totalNum:{
          type:Number,
          default:0
        },
        placement:{
          type:String,
          default:'bottom'
        },
        placeholder:{
          type:String,
          default:'',
        }
      },
      methods:{
        tableRowClick(row,type){  //单选列表行点击事件
          console.log(type,row);
        },
        selectionChange(row){ //多选列表复选框点击事件
          this.selectData = row
        },
        cancel(){  
          this.visible = false
        },
        handlePopoverShow(){  //弹出框显示触发
          this.$emit('handlePopoverShow',true)
        },
        handleSizeChange(val) { //分页条数
          this.$emit('handleSizeChange',val)
        },
        handleCurrentChange(val) {  //分页页数
          this.$emit('handleCurrentChange',val)
        },
        handleSelectData(){	//确认触发事件
          this.$emit('handleSelectData',this.selectData)
          this.visible = false
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .popover{
      float: right;
      padding-bottom: 0px;
    }
    .PopoverQuery{
      overflow: hidden;
      &-FormItem{
        margin-bottom: 0px;
      }
      &-Input{
        float: left;
        width: 70%;
        margin-right: 10px;
      }
    }
    ::v-deep .el-table__header-wrapper{
      position: sticky;
      top: -12px;
      z-index: 9;
    }
    ::v-deep .el-table__body-wrapper {
      height: 310px;
      overflow-y: scroll;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161

    这里我们要用到的字段除了上述的还有很多,因为这个是内置了三个组件的封装组件。

    封装思路

    • placement:位置
    • popoverText:按钮文字
    • popoverIcon:按钮图表
    • width:宽度
    • tableType:MultipleChoice(单选)、CheckBox(多选)
    • tableData:列表数据
    • tableConfig:列表配置
    • loading:开启列表加载
    • totalNum:分页总数
    • handlePopoverShow:弹出框显示触发
    • handleSizeChange:分页条数
    • handleCurrentChange:分页页数
    • handleSelectData:确定触发事件
    1. 首先是将placement,popoverText,popoverIcon,tableType,width传给组件定义按钮的样式,类型
    2. 点击按钮触发handlePopoverShow函数,将事件传给页面,页面开始请求接口,这时会将loading该为开启状态
    3. 后端回传数据后,将loading状态重置,在将tableData,tableConfig,totalNum传给组件,此时列表中已经可以查看到数据了
    4. 最后handleSelectData在执行剩下的逻辑

    我这里面还嵌入了一个form表单来作为数据的校验,但是还没写全,其实就是按照正常的form表单验证写就行了

    页面中使用

      //调用示例
      <Popover 
        style="float: left;height: 28px;"
        placement="right"
        :popoverText="this.$t('add_product_details')" 
        popoverIcon="el-icon-thumb"
        :tableData="productTableData" 
        :tableConfig="productTableConfig"
        :tableType="'CheckBox'"
        :loading="productTableloading"
        :totalNum="paging.totalNum"
        width="800"
        @handlePopoverShow="getFirstLegOrderlog"
        @handleSizeChange="handleSizeChange"
        @handleCurrentChange="handleCurrentChange"
        @handleSelectData="handleSelectData"
      >
      </Popover>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

  • 相关阅读:
    Spring+SpringBoot+SpringCloud全攻略
    ThreadLocal
    GO语言网络编程(并发编程)runtime包
    蓝桥杯刷题day13——乘飞机【算法赛】
    BIGEMAP APP行车(走路)轨迹记录
    毕业设计- 基于单片机与GPS+GSM的车辆定位跟踪系统
    从React源码角度看useCallback,useMemo,useContext
    Spring
    【ManageEngine卓豪 】助力世界顶尖音乐学院--茱莉亚学院,提升终端安全
    AWS 中文入门开发教学 37- 连接MySQL - phpMyAdmin 管理工具
  • 原文地址:https://blog.csdn.net/weixin_44748171/article/details/133307673