Vue + ElementUI 之el-table的二次封装,带条件查询及翻页功能
Posted 在奋斗的大道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue + ElementUI 之el-table的二次封装,带条件查询及翻页功能相关的知识,希望对你有一定的参考价值。
在实际开发后台项目中会存在很多表格,表格数据过多就需要分页和按条件筛选搜索查询,于是就对el-table进行了二次封装。
页面效果如图:
第一步:首先创建一个 searchForm.vue 文件,放置筛选查询条件和按钮。
<template>
<el-form :label-width="labelWidth" label-position="right" size="small" class="search-form" >
<el-container>
<el-row ref="target" type="flex" class="search-form_row">
<slot></slot>
<div class="el-form-item el-form-item--small">
<div class="el-form-item__content">
<el-button type="primary" size="small" @click="$emit('query')">查 询</el-button>
<el-button size="small" v-if="$slots.default" @click="$emit('reset')">重 置</el-button>
</div>
</div>
</el-row>
</el-container>
</el-form>
</template>
<script>
export default {
name: 'SearchForm',
props: {
labelWidth: {
type: String,
default: '70px'
},
}
}
</script>
第二步、创建 searchTable.vue 文件
<template>
<el-container class="search-table">
<el-header class="search-table__header" v-if="$slots.row">
<search-form ref="form"
:label-width="labelWidth"
@query="$emit('query')"
@reset="$emit('reset')">
<template>
<slot name="row"></slot><!-- 搜索条件 & 按钮 -->
</template>
</search-form>
</el-header>
<el-main class="search-table__body">
<el-row ref="actions" v-if="$slots.actions" class="search-table__action">
<el-col :span="24">
<slot name="actions"></slot><!-- 操作按钮 -->
</el-col>
</el-row>
<el-table ref="tableRef" :height="tableHeight"
:data="tableData"
:empty-text="emptyText"
stripe
border
highlight-current-row
:row-class-name="rowClassName"
tooltip-effect="light"
:header-cell-style="{ fontWeight: 'bold' }"
size="mini"
:row-key="rowKeys"
v-loading="tableLoading"
:default-sort="defaultSort"
@sort-change="handleSortChange"
@selection-change="
selection => {
this.$emit('selectionChange', selection)
}"
@select-all="
selection => {
this.$emit('selectAll', selection)
}"
>
<slot></slot>
</el-table>
</el-main>
<el-footer class="search-table__footer" height="42px" v-if="$slots.footer">
<slot name="footer"></slot>
</el-footer>
</el-container>
</template>
<script>
import SearchForm from './searchForm'
export default {
name: 'SearchTable',
components: { SearchForm },
props: {
labelWidth: {
type: String,
default: '70px'
},
tableData: {
type: Array,
default: () => []
},
emptyText: {
type: String,
default: ''
},
rowClassName: {
type: Function
},
rowKeys: {
type: Function
},
tableLoading: Boolean,
defaultSort: {
type: Object,
default: () => {}
},
},
data() {
return {
tableHeight: '400px' //table表格高度
}
},
methods: {
// 表格排序
handleSortChange(event) {
const { prop, order } = event
this.$emit('sortChange', {
prop,
order: order ? String.prototype.replace.call(order, 'ending', '') : null
})
}
}
}
</script>
第三步、业务模块使用封住组件(基本)
<style>
</style>
<template>
<el-card class="full-height full-width">
<search-table class="full-height full-width"
:table-loading="loading"
:tableData="tableData"
:ref="tableRef"
:labelWidth="'40px'"
:row-keys="row => row.id"
@query="currentPage = 1; query();"
@reset="doReset"
@selectionChange="selectionChange">
<template v-slot:row>
<el-form-item label="名称">
<el-input placeholder="请输入内容" v-model="searchForm.name" clearable></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input placeholder="请输入内容" v-model="searchForm.telphone" clearable></el-input>
</el-form-item>
<el-form-item label="QQ">
<el-input placeholder="请输入内容" v-model="searchForm.qq" clearable></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select placeholder="请选择" v-model="searchForm.gender" clearable>
<el-option :label="'男'" :value="1"></el-option>
<el-option :label="'女'" :value="2"></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:actions>
<el-button size="small" type="primary" >新 建</el-button>
<el-button size="small" type="primary" >编 辑</el-button>
<el-button size="small" type="primary" >删除/批量删除</el-button>
</template>
<template >
<el-table-column :reserve-selection="true" type="selection" width="55" />
<el-table-column prop="name" label="姓名" show-overflow-tooltip />
<el-table-column prop="gender" label="性别" :formatter="formatGenderType" show-overflow-tooltip />
<el-table-column prop="telphone" label="电话" show-overflow-tooltip />
<el-table-column prop="qq" label="QQ" show-overflow-tooltip />
<el-table-column prop="userName" label="客户专员" show-overflow-tooltip />
<el-table-column prop="levelName" label="客户级别" show-overflow-tooltip />
<el-table-column prop="stateName" label="客户状态" show-overflow-tooltip />
<el-table-column prop="address" label="地址" show-overflow-tooltip />
</template>
<template v-slot:footer>
<el-pagination
background
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</template>
</search-table>
</el-card>
</template>
<script>
import SearchTable from '@/components/searchTable'
import {getCustomerList} from "@/api/customer";
export default{
name: 'customer',
components: {
SearchTable
},
data () {
return {
tableData: [],
loading: false,
tableRef: 'tableRef',
searchForm: {},
currentPage: 1,
pageSizes: [10, 20, 50],
pageSize: 10,
total: 0,
genderArry:[{
"id": 1,
"name": "男"
},{
"id": 2,
"name": "女"
}],
markArry:[{
"id": 1,
"name": "未删除"
},{
"id": 2,
"name": "已删除"
}],
};
},
created() {
this.query()
},
methods: {
query() {
// 请求表格数据
var params ={
'pageNum': this.currentPage,
'pageSize': this.pageSize,
'name':this.searchForm.name,
'telphone':this.searchForm.telphone,
'qq':this.searchForm.qq,
'gender':this.searchForm.gender
}
getCustomerList(params).then(res => {
console.log(res)
// 把请求到的数据给testDatas数组
this.tableData = res.data.list
// 当前页数
this.currentPage = res.data.pageNum
// 当前页数量
this.pageSize = res.data.pageSize
// 分页总数
this.total = res.data.total
// console.log(JSON.stringify(res.data.data.total))
})
.catch((error) => {
console.log(error)
})
},
doReset() {
// 重置搜索条件
// 请求表格数据
this.tableData = [];
this.restForm();
this.query();
},
restForm(){
this.searchForm.name = ""
this.searchForm.telphone = ""
this.searchForm.qq = ""
this.searchForm.gender = ""
},
selectionChange(val) {
// 表格选项发生变化
console.log("触发表格事件")
this.selectionList = []
val.forEach(element => {
this.selectionList.push(element.id)
});
},
handleSizeChange(val) {
// 改变每页条数
this.pageSize = val
this.query()
},
handleCurrentChange(val) {
// 切换页码
this.currentPage = val
this.query()
},
// table 数据转换
formatGenderType(row, column){
if(row.gender === 1){
return '男'
} else if(row.gender === 2) {
return '女'
} else {
return ''
}
},
}
}
</script>
第四步:进步业务组件功能(新增、修改和删除功能)
<style>
</style>
<template>
<el-card class="full-height full-width">
<search-table class="full-height full-width"
:table-loading="loading"
:tableData="tableData"
:ref="tableRef"
:labelWidth="'40px'"
:row-keys="row => row.id"
@query="currentPage = 1; query();"
@reset="doReset"
@selectionChange="selectionChange">
<template v-slot:row>
<el-form-item label="名称">
<el-input placeholder="请输入内容" v-model="searchForm.name" clearable></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input placeholder="请输入内容" v-model="searchForm.telphone" clearable></el-input>
</el-form-item>
<el-form-item label="QQ">
<el-input placeholder="请输入内容" v-model="searchForm.qq" clearable></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select placeholder="请选择" v-model="searchForm.gender" clearable>
<el-option :label="'男'" :value="1"></el-option>
<el-option :label="'女'" :value="2"></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:actions>
<el-button size="small" type="primary" v-on:click="addCustomer()">新 建</el-button>
<el-button size="small" type="primary" v-on:click="editCustomer()">编 辑</el-button>
<el-button size="small" type="primary" v-on:click="handlerDelete()">删除/批量删除</el-button>
</template>
<template >
<el-table-column :reserve-selection="true" type="selection" width="55" />
<el-table-column prop="name" label="姓名" show-overflow-tooltip />
<el-table-column prop="gender" label="性别" :formatter="formatGenderType" show-overflow-tooltip />
<el-table-column prop="telphone" label="电话" show-overflow-tooltip />
<el-table-column prop="qq" label="QQ" show-overflow-tooltip />
<el-table-column prop="userName" label="客户专员" show-overflow-tooltip />
<el-table-column prop="levelName" label="客户级别" show-overflow-tooltip />
<el-table-column prop="stateName" label="客户状态" show-overflow-tooltip />
<el-table-column prop="address" label="地址" show-overflow-tooltip />
</template>
<template v-slot:footer>
<el-pagination
background
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</template>
</search-table>
<el-dialog title="修改客户" :visible.sync="dialogFormEdit" size="tiny">
<el-form id="#editsForm" ref="edits" :model="customer" label-width="80px" >
<el-form-item label="客户姓名" >
<el-col :span="7">
<el-input v-model="customer.name" auto-complete="off" ></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户性别" >
<el-col :span="7">
<el-select v-model="customer.gender" value-key="id">
<el-option v-for="item in genderArry" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户电话" >
<el-col :span="7">
<el-input v-model="customer.telphone" auto-complete="off"></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户QQ" >
<el-col :span="7">
<el-input v-model="customer.qq" auto-complete="off"></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户地址" >
<el-col :span="14">
<el-input v-model="customer.address" auto-complete="off" ></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户备注" >
<el-col :span="14">
<el-input v-model="customer.note" auto-complete="off" type="textarea"
:rows="2">
</el-input>
</el-col>
</el-form-item>
<el-form-item label="客户标记" >
<el-col :span="7">
<el-select v-model="customer.mark" value-key="id">
<el-option v-for="item in markArry" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户专员" >
<el-col :span="7">
<el-select v-model="customer.userId" value-key="id">
<el-option v-for="item in userArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户级别" >
<el-col :span="7">
<el-select v-model="customer.levelId" value-key="id">
<el-option v-for="item in levelArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户状态" >
<el-col :span="7">
<el-select v-model="customer.stateId" value-key="id">
<el-option v-for="item in stateArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormEdit = false">取 消</el-button>
<el-button type="primary" @click="edit(customer)">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="添加客户" :visible.sync="dialogFormAdd" size="tiny">
<el-form id="#addsForm" ref="addsForm" :model="customer" label-width="80px" >
<el-form-item label="客户姓名" >
<el-col :span="7">
<el-input v-model="customer.name" auto-complete="off" ></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户性别" >
<el-col :span="7">
<el-select v-model="customer.gender" value-key="id">
<el-option v-for="item in genderArry" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户电话" >
<el-col :span="7">
<el-input v-model="customer.telphone" auto-complete="off"></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户QQ" >
<el-col :span="7">
<el-input v-model="customer.qq" auto-complete="off"></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户地址" >
<el-col :span="14">
<el-input v-model="customer.address" auto-complete="off" ></el-input>
</el-col>
</el-form-item>
<el-form-item label="客户备注" >
<el-col :span="14">
<el-input v-model="customer.note" auto-complete="off" type="textarea"
:rows="2">
</el-input>
</el-col>
</el-form-item>
<el-form-item label="客户标记" >
<el-col :span="7">
<el-select v-model="customer.mark" value-key="id">
<el-option v-for="item in markArry" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户专员" >
<el-col :span="7">
<el-select v-model="customer.userId" value-key="id">
<el-option v-for="item in userArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户级别" >
<el-col :span="7">
<el-select v-model="customer.levelId" value-key="id">
<el-option v-for="item in levelArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="客户状态" >
<el-col :span="7">
<el-select v-model="customer.stateId" value-key="id">
<el-option v-for="item in stateArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormAdd = false">取 消</el-button>
<el-button type="primary" @click="add(customer)">确 定</el-button>
</div>
</el-dialog>
</el-card>
</template>
<script>
import SearchTable from '@/components/searchTable'
import {getCustomerList, batchDelete, insert, getById, update} from "@/api/customer";
import { Message} from "element-ui";
import {getLevelList} from "@/api/level";
import {getList} from "@/api/state";
import {getUserList} from "@/api/user";
export default{
name: 'customer',
components: {
SearchTable
},
data () {
return {
tableData: [],
loading: false,
tableRef: 'tableRef',
searchForm: {},
currentPage: 1,
pageSizes: [10, 20, 50],
pageSize: 10,
total: 0,
selectionList:[], //定义删除/批量删除
dialogFormAdd:false,
dialogFormEdit: false,
customer:{
id:'',
name:'',
address:'',
gender:'',
levelId:'',
levelName:'',
mark:'',
note:'',
qq:'',
stateId:'',
stateName:'',
telphone:'',
userId:'',
userName:''
},
genderArry:[{
"id": 1,
"name": "男"
},{
"id": 2,
"name": "女"
}],
markArry:[{
"id": 1,
"name": "未删除"
},{
"id": 2,
"name": "已删除"
}],
levelArray:[],
stateArray:[],
userArray:[]
};
},
created() {
this.query()
},
methods: {
query() {
// 请求表格数据
var params ={
'pageNum': this.currentPage,
'pageSize': this.pageSize,
'name':this.searchForm.name,
'telphone':this.searchForm.telphone,
'qq':this.searchForm.qq,
'gender':this.searchForm.gender
}
getCustomerList(params).then(res => {
console.log(res)
// 把请求到的数据给testDatas数组
this.tableData = res.data.list
// 当前页数
this.currentPage = res.data.pageNum
// 当前页数量
this.pageSize = res.data.pageSize
// 分页总数
this.total = res.data.total
// console.log(JSON.stringify(res.data.data.total))
})
.catch((error) => {
console.log(error)
})
},
doReset() {
// 重置搜索条件
// 请求表格数据
this.tableData = [];
this.restForm();
this.query();
},
restForm(){
this.searchForm.name = ""
this.searchForm.telphone = ""
this.searchForm.qq = ""
this.searchForm.gender = ""
},
selectionChange(val) {
// 表格选项发生变化
console.log("触发表格事件")
this.selectionList = []
val.forEach(element => {
this.selectionList.push(element.id)
});
},
handlerDelete(){
// 数组转字符串使用逗号分隔
let sids = this.selectionList.join(",")
var params ={
'sids': sids
}
batchDelete(params).then(res =>{
Message({
message: '批量删除成功',
type: 'success',
duration: 3 * 1000
})
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
},
handleSizeChange(val) {
// 改变每页条数
this.pageSize = val
this.query()
},
handleCurrentChange(val) {
// 切换页码
this.currentPage = val
this.query()
},
// table 数据转换
formatGenderType(row, column){
if(row.gender === 1){
return '男'
} else if(row.gender === 2) {
return '女'
} else {
return ''
}
},
// 新增客户
addCustomer(){
this.dialogFormAdd = true
// 初始化 等级数据和状态数据
this.initLevel()
this.initState()
this.initUser()
},
// 修改客户
editCustomer(){
// console.log('下标', index)
// console.log('数据', row)
console.log(this.selectionList)
console.log(typeof(this.selectionList))
let id = this.selectionList[0]
var params = {
'id' : id
}
getById(params).then(res =>{
//
this.customer = {}
this.customer = res.data
this.dialogFormEdit = true
// 初始化 等级数据和状态数据
this.initLevel()
this.initState()
this.initUser()
}).catch((error) => {
console.log(error)
})
},
// 初始化加载客户等级
initLevel(){
this.levelArray = []
getLevelList().then(res =>{
console.log(res)
// 输出级别初始化数据
let objects = res.data
objects.forEach(element => {
this.levelArray.push({'id':element.id, 'name': element.name})
});
})
},
// 初始化加载客户z状态
initState(){
this.stateArray = []
getList().then(res =>{
console.log(res)
// 输出级别初始化数据
let objects = res.data
objects.forEach(element => {
this.stateArray.push({'id':element.id, 'name': element.name})
});
})
},
initUser(){
this.userArray = []
getUserList().then(res =>{
console.log(res)
// 输出级别初始化数据
let objects = res.data
objects.forEach(element => {
this.userArray.push({'id':element.id, 'name': element.name})
});
})
},
add(customer){
insert(customer).then(res =>{
Message({
message: '客户新增成功',
type: 'success',
duration: 3 * 1000
})
// 新增弹出框隐藏
this.dialogFormAdd = false
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
},
edit(customer){
update(customer.id, customer).then(res =>{
Message({
message: '客户修改成功',
type: 'success',
duration: 3 * 1000
})
// 新增弹出框隐藏
this.dialogFormEdit = false
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
}
}
}
</script>
相关效果截图:
以上是关于Vue + ElementUI 之el-table的二次封装,带条件查询及翻页功能的主要内容,如果未能解决你的问题,请参考以下文章
elementUI+vue-cli el-table=》excel
vue+elementui进阶之路-el-table中显示图片
vue elementUI实现el-table 复选框默认选中,默认禁用,默认选中且禁用等效果