Aur*_*ret 5 javascript flux redux vuex vuejs2
我目前正在VueJS(尤其是Vuex)中编码应用程序。但是,我的问题与该库的联系并不紧密,而是与flux / redux / Vuex这样的商店拥有的体系结构紧密相关。
简单来说,我有几个API(每个团队一个API /数据库),每个团队/ API有几个用户,这些团队和用户由简单的对象表示,每个都有自己的子对象。重要说明:团队的成员当然是唯一的,但是团队的用户对于他们自己的团队而言是唯一的。用户的唯一性约束将为“ teamSlug / userSlug”。考虑到大量用户,我不能简单地加载所有团队的所有用户。
我的问题是如何正确构造我的应用程序/存储,以恢复给定用户数据块(与他的团队)的数据:如果我尚未加载此用户,请发出API请求以对其进行检索。当前,我已经创建了一个返回用户对象的吸气剂,该对象从用户和团队中获得了胜利。如果返回“ null”或带有“ .loading”到“ false”,我必须运行“ loadOne”动作,该动作将负责检索它:
import * as types from '../../mutation-types'
import users from '../../../api/users'
// initial state
const state = {
users: {}
}
// getters
const getters = {
getOne: state => (team, slug) => (state.users[team] || {})[slug] || null
}
// actions
const actions = {
loadOne ({ commit, state }, { team, slug }) {
commit(types.TEAM_USER_REQUEST, { team, slug })
users.getOne(team, slug)
.then(data => commit(types.TEAM_USER_SUCCESS, { team, slug, data }))
.catch(error => commit(types.TEAM_USER_FAILURE, { team, slug, error }))
}
}
// mutations
const mutations = {
[types.TEAM_USER_REQUEST] (state, { team, slug }) {
state.users = {
...state.users,
[team]: {
...(state.users[team] || {}),
[slug]: {
loading: true,
error: null,
slug
}
}
}
},
[types.TEAM_USER_SUCCESS] (state, { team, slug, data }) {
state.users = {
...state.users,
[team]: {
...(state.users[team] || {}),
[slug]: {
...data,
slug,
loading: false
}
}
}
},
[types.TEAM_USER_FAILURE] (state, { team, slug, error }) {
state.users = {
...state.users,
[team]: {
...(state.users[team] || {}),
[slug]: {
slug,
loading: false,
error
}
}
}
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
Run Code Online (Sandbox Code Playgroud)
您可以想象一个团队不仅有用户,而且我有许多其他类型的模型,我应该将它们链接在一起。此方法有效,但是我发现放置它非常麻烦(特别是这很简单,我将有很多其他此类操作)。您对我的体系结构有什么建议吗?
谢谢!
我发现保持 Vuex 存储灵活性的最佳方法是对其进行规范化并尽可能保持数据项平坦。这意味着将所有用户存储在一个结构中,并找到一种唯一标识他们的方法。
如果我们将团队和用户 slug 结合起来创建一个唯一标识符会怎样?以下是我对红队和蓝队用户的想象:
const state = {
users: {
allTeamSlugs: [
'blue1',
'blue2',
'blue3',
'red1',
'red2',
// etc...
],
byTeamSlug: {
blue1: {
slug: 1,
team: 'blue',
teamSlug: 'blue1'
},
// blue2, blue3, etc...
red1: {
slug: 1,
team: 'red',
teamSlug: 'red1'
},
// red2, etc...
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且teamSlugAPI 中的每个用户不需要都存在该属性。当您将数据加载到存储中时,您可以在突变中创建它。
const mutations = {
[types.TEAM_USER_SUCCESS] (state, { team, slug, data }) {
const teamSlug = [team, slug].join('')
state.users.byTeamSlug = {
...state.users.byTeamSlug,
[teamSlug]: {
...data,
slug: slug,
team: team,
teamSlug: teamSlug
}
}
state.users.allTeamSlugs = [
...new Set([ // The Set ensures uniqueness
...state.users.allTeamSlugs,
teamSlug
])
]
},
// ...
}
Run Code Online (Sandbox Code Playgroud)
那么你的吸气剂可能会像这样工作:
const getters = {
allUsers: state => {
return state.users.allTeamSlugs.map((teamSlug) => {
return state.users.byTeamSlug[teamSlug];
});
},
usersByTeam: (state, getters) => (inputTeam) => {
return getters.allUsers.filter((user) => user.team === inputTeam);
},
getOne: state => (team, slug) => { // or maybe "userByTeamSlug"?
const teamSlug = [team, slug].join('');
return state.users.byTeamSlug[teamSlug]; // or undefined if none found
}
}
Run Code Online (Sandbox Code Playgroud)
Redux 有一篇关于标准化的很棒的文章,我总是会回来阅读:https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape#designing-a-normalized-state