封装背景
管理后台需要大量的表格数据以及操作,可是用现有的element-ui,就显得代码有些冗余,维护起来乱糟糟的,所以就想到要将element-ui的table组件,分页组件进行二次的封装.以下内容是我参照juejin.cn/post/702214… 这篇文章进行修改得来的,仅供参考哦~
封装表格
子组件
<div>
<!--操作按钮-->
<el-row :gutter="20" class="btn-operation">
<el-col :span="5">
<el-switch v-model="switchValue" active-text="远程搜索" inactive-text="本地搜索" :active-value="1" :inactive-value="0" />
</el-col>
<el-col :span="6">
<el-input v-model="tableContent" placeholder="请输入内容" @keyup.native.enter="searchContent">
<el-button slot="append" icon="el-icon-search" @click="searchContent" />
</el-input>
</el-col>
<el-col :span="6">
<el-dropdown trigger="click">
<el-button icon="el-icon-s-operation" size="mini">列设置</el-button>
<el-dropdown-menu slot="dropdown">
<span class="title">列设置</span>
<el-tree draggable :data="columns" :props="defaultProps" :allow-drop="allowDrop" @node-drop="handleDrop">
<span slot-scope="{ node, data }" class="tree-table-setting">
<el-switch v-model="data.show" @change="saveTableColumns" />
<span>{{ node.label }}</span>
</span>
</el-tree>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<!--表格-->
<div>
<el-table
ref="table"
:key="tableKey"
:data="tableData"
:height="tableHeight"
:row-style="{ height: '40px' }"
:cell-style="{ borderRight: 'none' }"
:header-cell-style="{ height: '40px', padding: 0, background: '#f6f8fa', color: '#333' }"
border
size="mini"
tooltip-effect="dark"
highlight-current-row
@row-click="handelTableClick"
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" />
<template v-for="item in columns">
<el-table-column
v-if="item.show"
:key="item.prop"
show-overflow-tooltip
:prop="item.prop"
:sortable="item.sortable"
:label="item.label"
:width="item.width"
:resizable="item.resizable"
>
<template slot-scope="scope">
<span>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</template>
<el-table-column />
</el-table>
<el-pagination
class="pagination-container"
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
export default {
props: {
// 控制列
columns: {
type: Array,
default: () => []
},
// 表格数据
tableData: {
type: Array,
default: () => []
},
// 列表总数
total: {
required: true,
type: Number
},
// 当前页
page: {
type: Number,
default: 1
},
// 每页展示数量
limit: {
type: Number,
default: 20
},
// 每页展示数量
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
}
},
// 操作项
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 分页背景
background: {
type: Boolean,
default: false
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
data() {
return {
// 表格key
tableKey: 1,
// 默认表格高度
tableHeight: 300,
// 列设置中 tree配置
defaultProps: {
children: 'children',
label: 'label'
},
tableContent: '', // 搜索的表格内容
switchValue: 0 // 远程/本地搜索按钮控制 0本地 1远程
}
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
watch: {
'tableContent'(val) {
if (!val) { // 清空搜索项
this.$emit('clear-content')
}
}
},
mounted() {
this.init()
},
updated() {
// 解决操作之后表格抖动的问题
this.$refs.table.doLayout()
},
methods: {
/**
* @author: xxx
* @description: 搜索表格内容
* 1为远程(后台搜索) 0为本地搜索
*/
searchContent() {
if (this.switchValue === 0) { // 本地搜索
const search = this.tableContent
const arr = this.tableData.filter(item => {
return Object.keys(item).some(key => {
if (String(item[key]).toLowerCase().indexOf(search) > -1) { // 搜索到相关信息
return item
}
})
})
this.$emit('search-content', arr)
} else { // 远程搜索
console.log('------远程搜索---------')
}
},
init() {
// 判断本地是否有表格配置数据 ? 加载 : 忽略
// 获取表格数据
// 重设表格高度
},
allowDrop(draggingNode, dropNode, type) {
// 仅允许Tree节点上下拖动
return type !== 'inner'
},
// Tree 拖动时更新表格
handleDrop() {
this.tableKey++
// 保存表格配置
this.saveTableColumns()
},
// 重置表格列设置
resetTable() {
// ... 忽略
},
// 显示隐藏切换 && 保存表格配置
saveTableColumns() {
window.sessionStorage.setItem('clueTable', this.columns)
},
// 选中表格行
handelTableClick(row) {
// ... 省略业务逻辑
},
// table多选操作
handleSelectionChange(val) {
// ... 省略业务逻辑
},
// 页码切换
handleSizeChange(val) {
this.$emit('pagination', { page: this.currentPage, limit: val })
},
// 每页展示数量切换
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
}
}
}
以上js中的代码,像tableHeight这类参数也可以单独从父组件中传进来使用,毕竟每个页面的表格高度都多少有所不同嘛
父组件 在父组件中,直接引入刚才所写好的组件,进行使用即可
<TableTest
:table-data="tableData"
:columns="tableColumns"
:total="pageTotal"
:page.sync="actQueryForm.current"
:limit.sync="actQueryForm.size"
@columns-change="onColumnsChange"
@selection-change="onTableSelectionChange"
@sort-change="onTableSortChange"
@search-content="searchContent"
@clear-content="clearContent"
@pagination="getActList"
/>
import TableTest from '../TableTest'
export default {
data(){
return {
tableData: [
{ desc: '123as', name: '张三', age: 18, sex: '男' },
{ desc: '123as', name: '李四', age: 22, sex: '女' },
{ desc: '123as', name: '王五', age: 10, sex: '男' },
{ desc: '123as', name: '张三', age: 13, sex: '男' },
{ desc: '123as', name: '李四', age: 23, sex: '女' },
{ desc: '123as', name: '王五', age: 14, sex: '男' }
],
tableColumns: [
{
prop: 'name', // 对应列内容的字段名
label: '姓名', // 显示的标题
width: '', // 对应列的宽度
resizable: true, // 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)
show: true, // 展示与隐藏
sortable: false // 对应列是否可以排序
},
{
prop: 'sex', // 对应列内容的字段名
label: '性别', // 显示的标题
width: '', // 对应列的宽度
resizable: true, // 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)
show: true, // 展示与隐藏
sortable: false // 对应列是否可以排序
},
{
prop: 'age', // 对应列内容的字段名
label: '年龄', // 显示的标题
width: '', // 对应列的宽度
resizable: true, // 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)
show: true, // 展示与隐藏
sortable: false // 对应列是否可以排序
},
{
prop: 'desc', // 对应列内容的字段名
label: '描述', // 显示的标题
width: '', // 对应列的宽度
resizable: true, // 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)
show: true, // 展示与隐藏
sortable: false // 对应列是否可以排序
}
],
}
},
created() {
// 在初始化阶段保存tableData的原始数据目的是为了在搜索时,清空数据导致数据的丢失(项目中可以在请求完tableData的数据,存到本地即可)
sessionStorage.setItem('table_data', JSON.stringify(this.tableData)) // 保存原始数据
},
methods:{
// 查询表格数据
searchContent(arr) {
this.tableData = arr
},
// 查询后清空输入框信息
clearContent() {
this.tableData = JSON.parse(window.sessionStorage.getItem('table_data'))
},
}
}