一次使用vuex+element-table保存当页数据的过程记录
情景:修改盘存数量、损溢原因、备注勾选完后点击下一页再回来数据已经消失,由于分页数据被重新覆盖,现在需要保存。想到自己还没使用过vuex(应届生小白),所以尝试着在vuex保存已勾选的数据。
0.首先在vuex初始化相应数据。
在state.js中定义要保存数据的数组。
rows: []
在getter.js中
getRows: state => state.rows
mutation.js中定义相应的方法
},
insertRow: (state, row) => {
const index = state.rows.findIndex(item => {
return item.goodsId === row.goodsId
})
if (index === -1) {
state.rows.push(row)
}
},
deleteRow: (state, { goodsId }) => {
const index = state.rows.findIndex(item => {
return item.goodsId === goodsId
})
if (index !== -1) {
state.rows.splice(index, 1)
}
},
insertAllRow: (state, rows) => {
rows.forEach(item => {
let index = state.rows.findIndex(ele => {
return ele.goodsId === item.goodsId
})
if (index === -1) {
state.rows.push(item)
}
})
},
deleteAllRow: (state, rows) => {
rows.forEach(item => {
let index = state.rows.findIndex(ele => {
return ele.goodsId === item.goodsId
})
if (index !== -1) {
state.rows.splice(index, 1)
}
})
},
setRows: (state, list) => {
// state.rows = list || []
state.rows = JSON.parse(JSON.stringify(list))
},
updateRows: (state, row) => {
state.rows.find(v => {
return v.goodsId === row.goodsId ? v[row.type] = row[row.type] : ""
})
console.log(state, row)
},
1.在页面中获取vuex中的方法
// 选择数据存入 vuex 的 rows 中
...mapMutations({
insertItem: 'insertRow',
deleteItem: 'deleteRow',
insertAllItem: 'insertAllRow',
deleteAllItem: 'deleteAllRow',
updateRows: 'updateRows'
}),
在计算属性中获取vuex中定义的数组`
rows(){
return this.$store.state.rows
}
2.定义数据改变的回调
// 盘点数量修改
onInputChange(row,currentValue, oldValue){
this.findRows(row, 'endStock')
},
// 选择损益原因
changeReson(row){
this.findRows(row, 'lossReason')
},
// 选择供应商
changeSupplier(row){
this.findRows(row, 'supplierId')
},
// 修改备注
changeRemark(row){
this.findRows(row, 'remark')
},
findRows(row, str){
row.type = str
this.rows.find(v => {
if(v.goodsId === row.goodsId){
this.updateRows(row)
}
})
},
// 选中与取消勾选
selectRow (selection, row) {
const temp = this.rows.find((item) => {
return item.goodsId === row.goodsId
})
temp ? this.deleteItem({ goodsId: row.goodsId }) : this.insertItem(row)
this.selectGoodLists = JSON.parse(JSON.stringify(this.rows))
},
3.DOM结构
<el-table-column prop="endStock" label="盘点数量" width="220" sortable>
<template slot-scope="scope">
<el-input-number v-model="scope.row.endStock" :class="scope.row.isShowColor?'add_endstock':''" style="width: 190px;" :controls="true" :precision="0" :step="1" :min="0" :max="999999999" @change="(currentVal, oldVal) => onInputChange(scope.row, currentVal, oldVal)"></el-input-number>
</template>
</el-table-column>
<el-table-column prop="lossReason" label="损溢原因申报" min-width="155" sortable >
<!-- <template slot-scope="scope" >
<el-select v-model="scope.row.remark" filterable placeholder="请选择" clearable>
<el-option v-for="item in supplierIdList" :key="item.supplierId" :label="item.supplierName" :value="item.supplierId"></el-option>
</el-select>
</template> -->
<template slot-scope="scope">
<el-select v-model="scope.row.lossReason" filterable placeholder="请选择报损原因" clearable @change="changeReson(scope.row)" :disabled="goodsType == 2 || scope.row.firstCategoryId == '01' || scope.row.thirdCategoryId == '030600' || url.includes('StoreStockMiddle')" >
<el-option v-for="item in lossResson" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
<el-select v-model="scope.row.supplierId" filterable placeholder="请选择供应商(必选)" clearable v-if="scope.row.lossReason === '1'" @change="changeSupplier(scope.row)">
<!-- <p>{{scope.row.supplierId}}</p> -->
<el-option v-for="item in supplierIdList" :key="item.supplierId" :label="item.supplierName" :value="item.supplierId"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="260" sortable>
<template slot-scope="scope">
<el-input v-model="scope.row.remark" style="width: 220px;" type="text" @change="changeRemark(scope.row)"></el-input>
</template>
</el-table-column>
4.保存勾选状态
setChecked(){
this.tableData.forEach(item => {
let obj = this.rows.find(ele => {
return ele.goodsId === item.goodsId
})
if (obj) {
this.$refs.table.toggleRowSelection(item, true)
}
this.rows.map(v => {
if(v.goodsId === item.goodsId){
item.endStock = v.endStock || ""
item.lossReason = v.lossReason || ""
item.remark = v.remark || ""
item.supplierId = v.supplierId || ""
}
})
})
5.后来发现仍然没有被保存勾选状态,想着可能是渲染的问题,于是加了一下代码。
this.$nextTick(() => {
this.setChecked()
})
渲染勾选状态成功
6.最后数据也保存成功,但是我发现如果我先勾选再去改变相应的值,会弹出一下报错。之前也报过,原因是不能在vuex外部修改仓库里面的值,所以我创建了一个相应的方法去调用改变仓库里面的值。但是现在还报错。如下
7.虽然数据还是保存成功了,但是看到这个错误还是要解决,因为是先勾选再改变值的触发change函数报的错,所以我去注释掉那个函数。没有这个函数应该就不会报错了吧。但是出乎我意料,它仍然报错,我心想事件都没了你报什么错啊,于是我一步一步排查。找到了是这行代码的报错,如下。
temp ? this.deleteItem({ goodsId: row.goodsId }) : this.insertItem(row)
这里是一个简单的赋值,想到dom结构使用的是双向绑定。于是我就想会不会是改变input框值然后绑定了vuex里面的数据导致去修改vuex的数据而报的错,然后我就给他深拷贝了一份。代码变成如下:
temp ? this.deleteItem({ goodsId: row.goodsId }) : this.insertItem(JSON.parse(JSON.stringify(row)))
再运行,报错消失。ok这个问题完美解决。只是个小菜鸟记录第一次使用vuex,勿喷,如有更好的方法,请指教。