Ведение связанных объектов в Vue - PullRequest
0 голосов
/ 08 апреля 2020

Я новичок в vue, но я внимательно читаю документы по vue и vuex. Но я застрял со следующей проблемой. Я также думаю, что это не то, что я бы не сделал это как-то, но я бы хотел go за чистый и, вероятно, лучший практический подход.

Настройка: - У меня есть некоторые сущности - у меня есть некоторые пользователи - допустим, сущность может принадлежать нескольким пользователям

Теперь, что я хочу сделать sh, это отобразить список всех пользователей, у которых отмечены те, которые назначены сущности.

У меня есть следующее хранилище 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-Component загружает пользователей из хранилища в пределах созданного хука. Данные сущности извлекаются из хранилища из вычисленного свойства 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>

У меня также есть второй список всех пользователей, принадлежащих объекту в шаблоне того же компонента, как показано ниже, который я хотел бы сохранить в синхронизации c с «списком выбора». Таким образом, все пользователи с установленным флажком должны быть перечислены в этом списке:

<ul>
   <li v-for="user in entity.users" :key="user.id">
      {{user.name}}
    </li>
</ul>

И вот где я застрял: следует ли использовать вычисляемое свойство для device.users с помощью get () и set () и использовать это как v-модель на флажках? Я попробовал это, но это не сработало, потому что пользовательский объект из списка всех пользователей и объекты из списка device.users не были одинаковыми объектами, даже если они представляют одного и того же пользователя. И в этот момент я думаю, что я делаю все это сложным образом, и я просто упускаю из виду общий путь, которым практиковали бы vue -пользователи.

Короче говоря: что лучше способ решить эту задачу? Я думаю, что это наиболее распространенная задача.

Спасибо за каждый ответ, если потребуется больше кода / подробностей, я предоставлю их!

1 Ответ

1 голос
/ 08 апреля 2020

Как выглядит структура сущности? Предполагая, что у них есть массив 'users', вы можете вычислить значение для флажка, предоставив базовую c javascript функцию, которая проверяет, есть ли уникальный идентификатор этого пользователя в списке для этой сущности.

In 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)
}

Затем предоставьте простую функцию для значения флажка, которое возвращает true или false: :value="userIdsWithEntity.includes(user.id)"

Вместо v-модели (то есть: значение и @ input / @ изменяются, чтобы обновить свойство, представленное в: value, объединенном в одну директиву, чтобы вы могли столкнуться с определением вашего: value), используйте @ измените для обработки (не) проверки флажка, отправляя действие vuex, чтобы удалить / добавить этого пользователя в объект.

...