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>

研究良久,創作不易,記得點贊加留言哦

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