Я разрабатываю приложение, также использующее Vuex, и просто попал в ситуацию, когда работа с вложенными объектами будет болезненной, поэтому я стараюсь максимально нормализовать (сгладить) состояние, как в примере ниже:
users: {
1234: { ... },
46473: { name: 'Tom', topics: [345, 3456] }
},
userList: [46473, 1234]
Мой вопрос: Каков «лучший» способ достичь вышеизложенного, когда ваш ответ API выглядит следующим образом :
data: [
{id: 'u_0001', name: 'John', coments: [{id: 'c_001', body: 'Lorem Ipsum'}, {...}],
{id: 'u_0002', name: 'Jane', coments: [{id: 'c_002', body: 'Lorem Ipsum'}, {...}],
{...}
]
Предположим, для примера, что comments
является подмодулем users
:
Вариант 1:
// action on the user module
export const users = ({ commit, state }, users) => {
commit(SET_USERS, users)
commit('comments/SET_COMMENTS', users)
}
// mutation on the user module
[types.SET_USERS] (state, users) {
state.users = users.reduce((obj, user) => {
obj[user.id] = {
id: user.id,
name: user.name,
comments: user.comments.map(comment => comment.id)
}
return obj
}, {})
state.userIds = users.map(user => user.id)
},
// mutation on the comments module
[types.SET_COMMENTS] (state, users) {
let allComments = []
users.forEach(user => {
let comments = user.comments.reduce((obj, comment) => {
obj[comment.id] = comment
return obj
}, {})
allComments.push(comments)
})
state.comments = ...allComments
},
IMO, эта опция хороша, потому что вам не нужно беспокоиться о сбросе состояния каждый раз, когда вы меняете страницы (SPA / Vue-Router), избегая сценария, когда по какой-то причине id: u_001
больше не существует, потому что состояние отменяется каждый раз, когда вызывается мутация, но странно передавать users array
обеим мутациям.
Вариант 2:
// action on the user module
export const users = ({ commit, state }, users) => {
// Here you would have to reset the state first (I think)
// commit(RESET)
users.forEach(user => {
commit(SET_USER, user)
commit('comments/SET_COMMENTS', user.comments)
})
}
// mutation on the user module
[types.SET_USER] (state, user) {
state.users[user.id] = {
id: user.id,
name: user.name,
comments: user.comments.map(comment => comment.id)
}
state.userIds.push(user.id)
},
// mutation on the comments module
[types.SET_COMMENTS] (state, comments) {
comments.forEach(comment => {
Vue.set(state.comments, comment.id, comment)
})
state.commentsIds.push(...comments.map(comment => comment.id)
},
В этой ситуации необходимо сбросить состояние, иначе у вас будут повторяться / старые значения каждый раз, когда вы покидаете страницу и повторно переносите страницу. Это немного раздражает и более предрасположено к ошибкам или непоследовательному поведению.
Заключение
Как вы, ребята, справляетесь с такими сценариями и советами / передовым опытом? Ответы очень ценятся, так как я застрял на этих вещах.
Кроме того, я стараюсь избегать сторонних библиотек, таких как Vue ORM, normalizr и т. Д., Потому что потребности не так сложны.
Спасибо,
PS: в коде могут быть ошибки, так как я написал его без тестирования, пожалуйста, обратите внимание на общую картину.