問題描述
Elementui 使用el-table + el-pagination進行數據展示,前端自定義table分頁方法進行排序後,table綁定的data數據不是排序後的數據,且排序後修改當前內容時出現數據修改混亂。
原因分析
Table點擊排序後綁定的數據實際未發生改變,只有顯示的數據發生改變。
解決方案
自定義排序事件,排序後將綁定的數據更新爲排序後的數據。
難點和注意點
- 重置無法生效問題請先看vue + elementui表單重置 resetFields問題(無法重置表單)
- 後端一次性返回數據,前端自定義分頁方法,使用管道
- 排序後的數據只存儲當前頁的數據,所以更新時要只更新當前頁數據,當點擊另一頁時,顯示數據已更新,但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>