• Vue + ElementUI管理系统中 Table表格 二次封装


    前言:

    项目中,使用vue + element 的后台管理系统中 用的table表格很多,而且大部分很相似,一遍遍的写,代码会变得很冗余,

    于是利用Vue + Element  Table 重新封装出了一套表格组件。

    下面是常见的table效果图:

    包含页面跳转、属性过滤、图片、文字颜色显示、switch切换、操作栏等,

    数据使用了 mockjs 创建

    1. 在 component中 创建文件夹 talbeData 添加文件 index.vue

    <template>
      <div class="app-container">
        <el-table
          :data="dataList"
          v-loading="loading"
          border
          fit
          highlight-current-row
          style=" 100%;"
          @selection-change="handleSelectionChange"
          @sort-change="handleSortChange">
          <!-- 是否有多选 -->
          <el-table-column type="selection" width="55" v-if="table_config.isCheckBox"></el-table-column>
          <!-- 是否需要序号 -->
          <el-table-column type="index" label="序号" width="55" align="center" v-if="table_config.isIndex"/>
    
          <el-table-column
            v-for="item in table_config.thead"
            :key="item.prop" 
            :prop="item.prop" 
            :label="item.label"
            :min-width="item.minWidth"
            :sortable="item.sortable ? true : false"
            align="center">
            <template slot-scope="scope">
              <!-- 有状态过滤 -->
              <span v-if="item.filter" :class="item.specialClass && item.specialClass(scope.row)">
                {{item.callback && item.callback(scope.row)}}
              </span>
              <!-- 图片展示 -->
              <img v-else-if="item.image" :src="scope.row[item.prop]" style="40px; height: 40px">
              <!-- switch开关 -->
              <el-switch
                v-else-if="item.switch"
                v-model="scope.row[item.prop]"
                active-text="启用"
                active-value = 1
                inactive-value = 0
                inactive-text="停用"
                @change="item.callback && item.callback(scope.row)"
              >
              </el-switch>
              <!-- 有跳转 -->
              <router-link 
                v-else-if="item.router" 
                :to="{path: item.routerPath, query: {name: scope.row[item.prop]}}"
              >
                {{ scope.row[item.prop]}}
              </router-link>
              <!-- 默认展示 -->
              <span v-else>{{ scope.row[item.prop]}}</span>
            </template>
          </el-table-column>
    
          <!-- 操作列 -->
          <el-table-column
            fixed="right"
            :label="table_config.operation.label"
            :width="table_config.operation.width"
            align="center"
            v-if="isShow">
            <template slot-scope="scope">
              <template v-if="table_config.operation.cols">
                <div class="btn" 
                  v-for="item in table_config.operation.cols.slice(0,2)" 
                  :key="item.label">
                  <el-button @click="item.handleRow(scope.row,item.label)" :type="item.type" size="small">
                    {{item.label}}
                  </el-button>
                </div>
              </template>
              <!-- 操作列超过3个,用更多下拉显示 -->
              <el-dropdown v-if="isShowOperationCols">
                <span class="el-dropdown-link">
                  更多<i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item 
                    v-for="item in table_config.operation.cols.slice(2)" 
                    :key="item.label" 
                    @click.native="item.handleRow(scope.row,item.label)">
                    {{item.label}}
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        config: {
          type: Object,
          default: () => {}
        },
        dataList: {
          type: Array,
          default: () => {
            return []
          }
        },
        loading: {
          type: Boolean,
          default: false
        }
      },
      data() {
        return {
          table_config: {
            thead: [],            // 表格头
            isCheckBox: false,    // 是否多选
            isIndex: false,      // 是否有序号
            isOperation: true,   // 是否有操作列表
            operation: {        // 操作
              cols: []
            },      
          }
        }
      },
      computed: {
        isShow() {
          return this.table_config.isOperation && this.table_config.operation.cols.length
        },
        isShowOperationCols() {
          let list = this.table_config.operation.cols
          return list.length && list.length > 2
        }
      },
      watch: {
        // 监听传过来的config,进行初始化
        config: {
          handler(newVal) {
            if(newVal) {
              this.initConfig()
            }
          },
          immediate: true
        }
      },
      mounted() {
        
      },
      methods: {
        // 初始化配置
        initConfig() {
          for(let key in this.config) {
            if(Object.keys(this.table_config).includes(key)) {
              this.table_config[key] = this.config[key]
            }
          }
          
        },
        // 多选事件
        handleSelectionChange(val) {
          this.$emit('selection-change', val)
        },
        // 排序事件
        handleSortChange(val) {
          this.$emit('sort-change', val)
        }
      }
    }
    </script>
    
    <style scoped>
    .btn{
      display: flex;
      justify-content: center;
      display: inline-block;
      margin: 5px 0 0 10px;
    }
    .btn:first-child{
      margin-left: 0;
    }
    .color1{
      color: red;
    }
    .color2{
      color: green;
    }
    .color3{
      color: blue;
    }
    .el-dropdown{
      margin-left: 10px;
      cursor: pointer;
    }
    </style>
    

      

    2.在组件中引用

    <template>
      <div>
        <tableData 
          :config="table_config"
          :dataList="dataList"
          :loading="loading"
          @selection-change="selectionChange"
          @sort-change="sortChange"
        />
    
        <pagination
          :total="total"
          :pageNum.sync="pages.pageNum"
          :limit.sync="pages.pageSize"
          @pagination="fetchData()" 
        />
      </div> 
    </template>
    
    <script>
    import { getList } from '@/api/table'
    import TableData from '@/components/tableData';
    import Pagination from '@/components/pagination';
    import { sexType,roleType } from '../utils/config';
    
    export default {
      components: {
        TableData,
        Pagination
      },
      data() {
        return {
          // 配置项
          table_config: {
            thead: [
              { 
                label: '姓名',
                prop: 'name',
                minWidth: '150px',
                router: true,
                routerPath: 'xxx'
              },
              {
                label: '性别',
                prop: 'sex',
                minWidth: '100px',
                filter: true,
                callback: (rowData) => {
                  let data = sexType[rowData.sex]
                  if(data) {
                    return data.label
                  }
                }
              },
              {label: '头像',prop: 'img',  minWidth: '100px',image: true},
              {label: '电话',prop: 'phone',minWidth: '150px',},
              {label: '时间',prop: 'time', minWidth: '200px',sortable: true},
              {
                label: '角色',
                prop: 'role',
                minWidth: '150px',
                filter: true,
                colorName: '',
                callback: (rowData) => {
                  let data = roleType[rowData.role]
                  if(data) {
                    return data.label
                  }
                },
                specialClass: (rowData) => {
                  let data = roleType[rowData.role]
                  if(data) {
                    return data.className
                  }
                }
              },
              {
                label: '状态',
                prop: 'status',
                minWidth: '150px',
                switch: true,
                callback: this.changeStatus
              },
            ],
            isCheckBox: true,
            isIndex: true,
            isOperation: true,
            // 表格操作列
            operation: {
              label: '操作',
               '200',
              cols: [
                {
                  label: '编辑',
                  type: 'primary',
                  handleRow: this.handleRow
                },
                {
                  label: '删除',
                  type: 'danger',
                  handleRow: this.handleRow
                }
              ]
            },
          },
          dataList: [],
          loading: false,
          pages: {
            pageNum: 1,
            pageSize: 10
          },
          total: 0
        }
      },
      mounted() {
        this.fetchData()
      },
      methods: {
        fetchData() {
          this.loading = true
          getList(this.pages).then(res => {
            if(res.data.code === 20000) {
              this.dataList = res.data.data.items
              this.total = res.data.data.total
              this.loading = false
            }
          })
          setTimeout(() => {
            this.loading = false
          },3000)
        },
         // 操作方法
        handleRow(rowData,label) {
          console.log(rowData,label);
        },
        // 多选方法
        selectionChange(val) {
          console.log(val);
        },
        // 排序方法
        sortChange(val) {
          console.log(val);
        },
        changeStatus(val) {
          console.log(val);
        }
      }
    }
    </script>

      

    3.配置参数

    table_config

    参数说明类型默认值
    thead 表格的列 Array []
    isCheckBox 是否多选 Boolean false
    isIndex 是否有序号 Boolean false
    isOperation 是否有操作列 Boolean true
    operation 操作列 Object -

    配置列 thead

    参数说明类型默认值
    label 标题 string -
    prop 字段名 string -
    minWidth 最小宽度 string -
    image 是否图片 Boolean false
    sortable 是否排序 Boolean false
    router 是否有跳转 Boolean false
    filter 是否有信息过滤 Boolean false
    switch 是否有开关 Boolean false
    routerPath 跳转地址 string -

    Table Events

    参数说明类型默认值
    selection-change 多选事件 Function -
    sort-change 排序事件 Function -

    table-column Events

    参数说明类型默认值
    callback 回调函数 Function(row) -
    specialClass 特殊字体颜色函数 Function(row) -
    handleRow 操作列回调函数 Function(row, label) -

    源码

    如果你感兴趣的话,请前往 GitHub 查看源码和完整文档。

    https://github.com/wangibook/my-table-component

  • 相关阅读:
    海明距离分类 JavaScript
    控制器语法糖
    中文版 ImageNet Classification with Deep Convolutional Neural Networks
    中文版 R-FCN: Object Detection via Region-based Fully Convolutional Networks
    中文版 Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
    Scrapy中scrapy.Request和response.follow的区别
    神马是回调函数?
    数据库索引原理及优化
    MYSQL数据库引擎区别详解
    数据库索引原理详解
  • 原文地址:https://www.cnblogs.com/wangdashi/p/16099897.html
Copyright © 2020-2023  润新知