Vue + Element-UI管理系统中 Table表格 二次封装

前言:

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

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

 

下面是常见的table效果图:

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

数据使用了 mockjs 创建

 

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

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<template>
  <div class="app-container">
    <el-table
      :data="dataList"
      v-loading="loading"
      border
      fit
      highlight-current-row
      style="width: 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="width: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.在组件中引用

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
<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: '操作',
          width: '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

 

posted @   王大师  阅读(1539)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示