在 Vue 中维护关联对象
Maintain associated objects in Vue
我是 vue 新手,但我也仔细阅读了 vue 和 vuex 的文档。但我遇到了以下问题。我也确实认为我不会以某种方式完成它,但我想采用一种干净且可能是最佳实践的方法。
设置:
- 我有一些实体
- 我有一些用户
- 假设一个实体可以属于多个用户
现在我想要完成的是显示所有选中并分配给实体的用户的列表。
我有以下 vuex 商店:
export default new Vuex.Store({
state: {
users: [],
entities: []
},
getters: {
USERS: state => state.users,
ENTITIES: state => state.entities,
ENTITY: state => id => {
return state.entities.find(entity => entity.id == id)
}
},
mutations: {
SET_USERS: (state, payload) => {
state.users = payload
},
SET_ENTITIES: (state, payload) => {
state.entities = payload
},
UPDATE_DEVICE: (state, payload) => {
state.entities = state.entities.map(entity => {
if(entity.id === payload.id){
return Object.assign({}, entity, payload.data)
}
return entity
})
}
},
actions: {
GET_USERS: async (context) => {
let { data } = await Axios.get('/api/v1/users')
context.commit('SET_USERS', data)
},
GET_ENTITIES: async (context) => {
let { data } = await Axios.get('/api/v1/entities')
context.commit('SET_ENTITIES', data)
},
UPDATE_ENTITY: ({commit}, payload) => {
Axios.put('/api/v1/entities/' + payload.id + '/', payload.data).then((response) => {
commit('UPDATE_ENTITY', payload)
});
}
}
})
我的实体组件从创建的挂钩中的商店加载用户。实体的数据是从计算 属性 entity()
的存储中获取的。此外,所有用户的列表由计算得到的 属性 users()
.
created(){
if(!this.$store.getters.USERS.length) this.$store.dispatch('GET_USERS')
},
computed: {
entity(){
const entityId = this.$route.params.id
return this.$store.getters.ENTITY(entityId)
},
users(){
return this.$store.getters.USERS
}
}
然后在模板中显示所有用户和一个复选框:
<ul>
<li v-for="(user, i) in users" :key="i">
<input type="checkbox" :value="user" :id="'user_'+i" :name="'user_'+i" v-model="???" />
<label :for="'user_'+i">{{user.name}}</label>
</li>
</ul>
我还有第二个列表,其中包含属于同一组件模板中的实体的所有用户,如下所示,我希望与 'selectable list' 保持同步。因此,所有选中复选框的用户都应列在该列表中:
<ul>
<li v-for="user in entity.users" :key="user.id">
{{user.name}}
</li>
</ul>
这就是我被困的地方:
我应该使用 get() 和 set() 为 device.users 计算的 属性 并将其用作复选框上的 v-model 吗?我试过了,但它没有用,因为所有用户列表的用户对象和 device.users 列表的对象不是相同的对象,即使它们代表相同的用户。在这一点上,我认为我正在以复杂的方式完成整个事情,而我只是忽略了练习 vue 用户的常见方式。
长话短说:解决此任务的最佳方法是什么?
我认为这是一项最常见的任务。
感谢您的每一个回答,如果需要更多代码/详细信息,我当然会提供!
实体的结构是什么样子的?假设他们有一个数组 'users',您可以通过提供一个基本的 javascript 函数来计算复选框的值,该函数检查该用户的唯一 ID 是否在该实体的列表中。
在 computed 中创建一个新的 属性(因此您不会为 v-for 中的每个元素重新计算相同的数组):
userIdsWithEntity() {
if (!this.entity) return []; // necessary in case entity hasn't been instantiated yet
return this.entity.users.map(x => x.id)
}
然后为returns真或假的复选框值提供一个简单的函数::value="userIdsWithEntity.includes(user.id)"
而不是 v-model(即 :value 和 @input/@change 以更新 :value 中提供的 属性 并整合到一个指令中,因此您可能会与 :value 定义发生冲突),使用@change 来处理复选框的(取消)检查,将一个动作分派到 vuex 到 remove/add 该用户到实体。
我是 vue 新手,但我也仔细阅读了 vue 和 vuex 的文档。但我遇到了以下问题。我也确实认为我不会以某种方式完成它,但我想采用一种干净且可能是最佳实践的方法。
设置: - 我有一些实体 - 我有一些用户 - 假设一个实体可以属于多个用户
现在我想要完成的是显示所有选中并分配给实体的用户的列表。
我有以下 vuex 商店:
export default new Vuex.Store({
state: {
users: [],
entities: []
},
getters: {
USERS: state => state.users,
ENTITIES: state => state.entities,
ENTITY: state => id => {
return state.entities.find(entity => entity.id == id)
}
},
mutations: {
SET_USERS: (state, payload) => {
state.users = payload
},
SET_ENTITIES: (state, payload) => {
state.entities = payload
},
UPDATE_DEVICE: (state, payload) => {
state.entities = state.entities.map(entity => {
if(entity.id === payload.id){
return Object.assign({}, entity, payload.data)
}
return entity
})
}
},
actions: {
GET_USERS: async (context) => {
let { data } = await Axios.get('/api/v1/users')
context.commit('SET_USERS', data)
},
GET_ENTITIES: async (context) => {
let { data } = await Axios.get('/api/v1/entities')
context.commit('SET_ENTITIES', data)
},
UPDATE_ENTITY: ({commit}, payload) => {
Axios.put('/api/v1/entities/' + payload.id + '/', payload.data).then((response) => {
commit('UPDATE_ENTITY', payload)
});
}
}
})
我的实体组件从创建的挂钩中的商店加载用户。实体的数据是从计算 属性 entity()
的存储中获取的。此外,所有用户的列表由计算得到的 属性 users()
.
created(){
if(!this.$store.getters.USERS.length) this.$store.dispatch('GET_USERS')
},
computed: {
entity(){
const entityId = this.$route.params.id
return this.$store.getters.ENTITY(entityId)
},
users(){
return this.$store.getters.USERS
}
}
然后在模板中显示所有用户和一个复选框:
<ul>
<li v-for="(user, i) in users" :key="i">
<input type="checkbox" :value="user" :id="'user_'+i" :name="'user_'+i" v-model="???" />
<label :for="'user_'+i">{{user.name}}</label>
</li>
</ul>
我还有第二个列表,其中包含属于同一组件模板中的实体的所有用户,如下所示,我希望与 'selectable list' 保持同步。因此,所有选中复选框的用户都应列在该列表中:
<ul>
<li v-for="user in entity.users" :key="user.id">
{{user.name}}
</li>
</ul>
这就是我被困的地方: 我应该使用 get() 和 set() 为 device.users 计算的 属性 并将其用作复选框上的 v-model 吗?我试过了,但它没有用,因为所有用户列表的用户对象和 device.users 列表的对象不是相同的对象,即使它们代表相同的用户。在这一点上,我认为我正在以复杂的方式完成整个事情,而我只是忽略了练习 vue 用户的常见方式。
长话短说:解决此任务的最佳方法是什么? 我认为这是一项最常见的任务。
感谢您的每一个回答,如果需要更多代码/详细信息,我当然会提供!
实体的结构是什么样子的?假设他们有一个数组 'users',您可以通过提供一个基本的 javascript 函数来计算复选框的值,该函数检查该用户的唯一 ID 是否在该实体的列表中。
在 computed 中创建一个新的 属性(因此您不会为 v-for 中的每个元素重新计算相同的数组):
userIdsWithEntity() {
if (!this.entity) return []; // necessary in case entity hasn't been instantiated yet
return this.entity.users.map(x => x.id)
}
然后为returns真或假的复选框值提供一个简单的函数::value="userIdsWithEntity.includes(user.id)"
而不是 v-model(即 :value 和 @input/@change 以更新 :value 中提供的 属性 并整合到一个指令中,因此您可能会与 :value 定义发生冲突),使用@change 来处理复选框的(取消)检查,将一个动作分派到 vuex 到 remove/add 该用户到实体。