Elementui table 前端自定义分页后排序

问题描述

Elementui 使用el-table + el-pagination进行数据展示,前端自定义table分页方法进行排序后,table绑定的data数据不是排序后的数据,且排序后修改当前内容时出现数据修改混乱。

原因分析

Table点击排序后绑定的数据实际未发生改变,只有显示的数据发生改变。

解决方案

自定义排序事件,排序后将绑定的数据更新为排序后的数据。

难点和注意点

  1. 重置无法生效问题请先看vue + elementui表单重置 resetFields问题(无法重置表单)
  2. 后端一次性返回数据,前端自定义分页方法,使用管道
  3. 排序后的数据只存储当前页的数据,所以更新时要只更新当前页数据,当点击另一页时,显示数据已更新,但table绑定的数据未更新

废话不多,直接上代码

<template>
	<div>
		<el-table :data="payoutPlanTable | pagination(pageNo,pageSize)" ref="payoutPlanTableRef" @sort_change="handlePayoutPlanSortChange" show-summary>
			<!-- 使用管道方式 | 过滤数据只显示当前页 自定义排序方法-->
			<el-tale-column prop="date" lable="日期" sortable></el-table-column>
			<el-tale-column prop="amt" lable="金额"></el-table-column>
			<el-table-column label="操作">
				<template slot-scope="scope">
					<el-button type="text" @click.native.prevent="doEdit('edit',scope.row,scope.$index)"></el-button>
				</template>
			</el-table-column>
		</el-table>
		<div style="margin-top: 10px;">
			<el-pagination
				layout="prev,pager,next"
				:current-page="pageNo"
				:total="payoutPlansTable.length"
				:page-size="pageSize"
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange"
			></el-pagination>
		</div>
		<div style="margin-top: 20px;">
			<el-button size="small" type="success" @click="doEdit('add')">新增</el-button>
		</div>
		<el-dialog title="新增/修改弹框窗口" :visible.sync="payoutPlanVisible" :close-on-click-modal="false" :show-close="false" :close-on-press-escape="false" size="small">
			<el-form :model="payout_plan" :rules="payoutPlanRules" ref="payoutPlanFormRef" labe-width="100px">
				<el-row :gutter="24">
					<el-col :span="10">
						<el-form-item label="日期" prop="date">
							<el-date-picker v-model="payout_plan.date" placeholder="日期" type="date"></el-date-picker>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="24">
					<el-col :span="10">
						<el-form-item label="金额" prop="amt">
							<el-input v-model.number="payout_plan.amt" placeholder="金额"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<div style="margin-top: 20px;">
					<el-row>
						<center>
							<el-button size="small" type="primary" @click="doOk">确定</el-button>
							<el-button size="small" @click="doCancel('payoutPlanFormRef')">确定</el-button>
						</center>
					</el-row>
				</div>
			</el-form>
		</el-dialog>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				payoutPlanTable: [],
				pageNo: 1,
				pageSize: 10,
				payoutPlanVisible: false,
				payout_plan: {
					date: '',
					amt: '',
					id: '',
					index: ''
				},
				payoutPlanRules: {
					date: [{required: true, message: '请选择日期'}],
					amt: [{type: 'number', required: true, message: '请输入数字', trigger: 'change'}]
				},
			}
		},
		filter: {
			//前端自定义分页
			pagination(table,pageNo,pageSize) {
				if(table.length >=1) {
					let offset=(pageNo - 1)*pageSize
					let data = (offset+pageSize >= table.length) ? table.slice(offset,table.length) : table.slice(offset,offset+pageSize)
				}else {
					return []
				}
			}
		},
		methods: {
			//**前端自定义排序方法,研究好久,记得点赞**
			handlePayoutPlanSortChange() {
				let afterSortArr = JSON.parse(JSON.stringify(this.$refs.payoutPlanFormRef.tableData)) //**重点:排序后数据存储在哪里**
				//如果没有分页,可直接赋值table绑定的data数据,请绕行
				let startI = 0
				let afterSortArrI = 0
				if(this.pageNo > 1) {
					startI = Number((this.pageNo-1) * this.pageSize)
				}
				//更新table数据啦
				for(let i = startI; i < (startI + Number(afterSortArr.length)); i++) {
					this.payoutPlanTable[i] = afterSortArr[afterSortArrI]
					afterSortArrI++
				}
			},
			handleSizeChange(val) {
				this.pageSize = val
			},
			handleCurrentChange(val) {
				this.pageNo = val
			},
			doEdit(flag,row,index) {
				if(flag == 'add') {
					this.payout_plan.index = null
					this.payoutPlanVisible = true
				}else {
					this.handlePayoutPlanSortChange()
					this.payoutPlanVisible = true
					this.$nextTick(function() { //resetFields方法无法生效注意这里哦
						let attrs=['date','id','amt']
						attrs.forEach(attr => {
							this.payout_plan[attr] = row[attr]
						})
						//**找准index**
						if(this.pageNo > 1) {
							this.payout_plan.index = (this.pageNo -1) * this.pageSize + Number(index)
						}else {
							this.payout_plan.index = index
						}
					})
				}
			},
			doOk() {
				if(this.payout_plan.index || this.payout_plan.index == '0') {
					let obj = {
						amt: parseFloat(this.payout_plan.amt),
						date: this.payout_plan.date,
						id: this.payout_plan.id
					}
					this.$set(this.payoutPlanTable,this.payout_plan.index,obj)
				}else {
					this.payoutPlanTable.push({
						amt: parseFloat(this.payout_plan.amt),
						date: this.payout_plan.date 
					})
				}
				this.doCancel('payoutPlanFormRef')
			},
			doCancel(formname) {
				this.$refs[formname].resetFields()
				this.payout_plan.index = null
				this.payoutPlanVisible = false
			},
		}
	}
</script>

研究良久,创作不易,记得点赞加留言哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章