Vuejs2 - Как обновить весь объект с сервера, не теряя реактивности? - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть список объектов, которые можно обновить из базы данных.

Итак, когда я загружаю список, объекты имеют только идентификатор и имя.

Когда я нажимаю на объектЯ загружаю другие поля, которые могут быть любой длины - поэтому я не загружаю их с объектами в списке.

Я обнаружил, что при обновлении объекта может быть трудно поддерживать реактивность https://vuejs.org/v2/guide/reactivity.html, поэтому мне нужно найти обходной путь.

этот код работает почти нормально:

    axios.get('/api/news', item.id).then(function(response){
        if (response){
            Object.assign(item, response.data.item);
        }
    });

Но проблема в том, что поля, которые не были представлены с самого начала, больше не 100%.То, что происходит, - это новое поле, которое обновлялось реактивно только тогда, когда я меняю другое, предыдущее.Итак, если я покажу 2 текстовых поля со старыми и новыми свойствами, если я изменю второе свойство, поле не будет обновлено, пока я не изменю первое.

Я получил объект элемента из компонента:

data () {
        return {
            items: [], 
        }
},

и

            <div v-for="item in items" @click="selectItem(item)" >
                <span>{{item.name}}</span>
            </div>

Затем элемент был передан в функцию selectItem.

Что такоеправильный шаблон для загрузки новых полей и держать их реактивными?(NB: это не тот случай, когда я могу назначить поле за полем - я хочу повторно использовать один и тот же код независимо от того, какой это объект, поэтому мне нужно решение для одновременного обновления объекта без перечисления всех новых полей.)

Примечание.Этот код работает внутри компонента.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Полностью пересмотренный пост: Хорошо, в приведенном вами примере используется массив, который имеет его собственные предостережения , в частности, вы не можете напрямую установить значения, например vm.items[indexOfItem] = newValue, и заставить его реагировать.

Таким образом, вы должны использовать Vue.set с массивом в качестве первого аргумента и индексом в качестве второго.Вот пример, который добавляет свойство name к элементам объекта, а затем использует Vue.set, чтобы установить элемент на новый объект, созданный Object.assign.

new Vue({
  el: '#app',
  data: {
    items: [{
      id: 1,
      other: 'data'

    }, {
      id: 2,
      other: 'thingy'
    }]
  },
  methods: {
    selectItem(parent, key) {
      const newObj = Object.assign({}, parent[key], {
        name: 'some new name'
      });

      Vue.set(parent, key, newObj);
      setTimeout(() => {parent[key].name = 'Look, reactive!';}, 1500);
    }
  }
});


  
    {{item.name || 'empty'}}
  
  
  {{JSON.stringify(items, null, 2)}}
  
0 голосов
/ 16 февраля 2019

Взгляните на Change-Detection-Caveats Vue не может обнаружить добавление или удаление свойства, если вы используете методы "обычного назначения".
Вы должны использовать Vue.set(object, key, value)
Попробуйте что-то вродеследующее:

axios.get('/api/news', item.id).then(function(response){
        if (response){
            let item = {}
            Vue.set(item, 'data', response.data.item)
        }
});

Чем item.data будет, чем реактивно.

...