I have an array of records. Each record is an object with _id (mongo id) , title, and value (value is an object with amount and currency).
I'm showing the list of records with v-for when ':key' of the list is the id of the record.
It works when I add a record, (using records.push()
in the store), and delete a record (using records.splice(idx, 1)
), But when I'm trying to edit a record and change the title or value.amount the list does not re-render and show the list without the change (using records.splice(idx, 1, updatedRecord))
Here My Code: Record List
<template> <ion-list> <ion-item> <ion-label>Date</ion-label> <ion-label>Title</ion-label> <ion-label>Value</ion-label> <ion-label /> </ion-item> <RecordPreview v-for="record in records":key="record._id":record="record" @onEditRecord="onEditRecord" @onDeleteRecord="onDeleteRecord" /> </ion-list> </template> <script> import { IonList, IonItem, IonLabel } from '@ionic/vue'; import RecordPreview from './RecordPreview.vue'; export default { name: 'RecordList', components: { RecordPreview, IonList, IonItem, IonLabel, }, props: { records: { type: Array, default: () => [], }, }, emits: ['onEditRecord', 'onDeleteRecord'], setup(_, { emit }) { function onEditRecord(record) { emit('onEditRecord', record); } function onDeleteRecord(record) { emit('onDeleteRecord', record); } return { onEditRecord, onDeleteRecord, }; }, }; </script>
Vuex record module
import recordService from '../../services/record.service'; export const recordModule = { state: () => ({ records: [], }), actions: { async getRecords({ commit }) { const records = await recordService.getRecords(); commit('setRecords', records); }, async addRecord({ commit }, record) { const newRecord = await recordService.addRecord(record); commit('addRecord', newRecord); }, async updateRecord({ commit }, record) { const res = await recordService.updateRecord(record); if (res.modifiedCount > 0) { commit('updateRecord', record); } }, async removeRecord({ commit }, recordId) { const res = await recordService.removeRecord(recordId); if (res.deletedCount > 0) { commit('removeRecord', recordId); return true; } return false; }, }, mutations: { setRecords(state, records) { state.records = records; }, addRecord(state, record) { state.records.push(record); }, updateRecord(state, updatedRecord) { const recordIdx = state.records.findIndex((rec) => rec._id === updatedRecord._id); state.records.splice(recordIdx, 1, updatedRecord); }, removeRecord(state, recordId) { const recordIdx = state.records.findIndex((rec) => rec._id === recordId); state.records.splice(recordIdx, 1); }, }, getters: { records(state) { return state.records; }, }, };
To get the records I'm using getter from the store placed on the parent component of RecordList like that:
const records = computed(() => store.getters.records);
PS I tried to create a deep copy of the array and replace all the array. I also tried to create a deep copy of the record, then change and replace it. And I think the problem is with the key, coz when I tried to change the:key from 'record._id' to 'record 'it re-render the list when I replaced the item (I guess it work because the pointer of the object was changed)
If you are fetching records from an API I recommend that you update by fetching from the API, and if you want to update the item within your state, try this:
updateRecord(state, updatedRecord) {
const { title, value } = updatedRecord;
const recordIdx = state.records.findIndex((rec) => rec._id === updatedRecord._id);
recordIdx.title = title
recordIdx.value = value
...
},
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.