在 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 该用户到实体。