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>

相关效果截图:

 

 

 

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于el-table的二次封装,可以通过以下步骤实现: 1. 创建一个新的组件,例如CustomTable.vue,用于封装el-table功能。 2. 在CustomTable.vue中引入el-tableel-table-column组件,并根据需要进行配置。 3. 在CustomTable.vue中定义props属性,用于接收父组件传递的数据和配置项。 4. 在CustomTable.vue中使用v-for指令遍历props中的配置项,动态生成el-table-column组件。 5. 在CustomTable.vue中使用props中的数据渲染el-table组件。 6. 在父组件中使用<CustomTable :data="tableData" :columns="tableColumns"></CustomTable>的方式引入CustomTable组件,并传递数据和配置项。 7. 在父组件中定义tableData和tableColumns,分别用于存储表格数据和表格列的配置。 8. 在父组件中修改tableData和tableColumns的值,即可动态更新CustomTable组件的表格数据和列的配置。 通过以上步骤,可以实现el-table的二次封装,省去了重复的el-table-column代码,提高了代码的可维护性和复用性。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [两种方式对el-table二次封装](https://blog.csdn.net/weixin_42375707/article/details/130042460)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值