Получатели Vuex не обновляются после повторного увлажнения магазина из постоянного хранилища - PullRequest
0 голосов
/ 14 декабря 2018

У меня странная проблема с настройкой Electron + Vue.

УСЛОВИЯ: Electron + Vue (я использовал шаблон ) + vuex-persist (также пытались vuex-persistedstate и vuex-persistfile ).

ПРОБЛЕМА: Получатели Vuex остаются 0 / пусто/ '' когда магазин подвергается регидратации.Откуда я это знаю?Если локальное хранилище чистое (я запускаю приложение в первый раз), состояние первой мутации обновляется (получатели возвращают правильные значения), и я вижу объект, добавляемый в локальное хранилище браузера.Однако когда приложение перезапускается , мутации вызывают состояние и обновление локального хранилища, как и раньше, НО геттеры остаются пустыми / по умолчанию.Ниже getter возвращает пустой массив.

enter image description here

SETUP: У меня есть приложение, которое работает со сторонним API: получает данные,рассчитывает вещи и отправляет некоторые данные обратно.API также требует авторизации.Ниже моя структура Vuex.

Часть моего объекта состояния ...

const state = {
  token: '',
  projects: [],
  work_packages: [],
  timeEntriesLocal: []
}

... и один из моих получателей:

const getters = {
  todayLog () {
    function sameDay (d1, d2) {
      return d1.getFullYear() === d2.getFullYear() &&
        d1.getMonth() === d2.getMonth() &&
        d1.getDate() === d2.getDate()
    }
    var entries = state.timeEntriesLocal
    var todayEntries = []
    entries.forEach(element => {
      var date = element.spentOn
      var today = new Date()
      if (sameDay(date, today)) {
        todayEntries.push(element)
      }
    })
    return todayEntries
  }
}

Возвращает записииз массива из-за «today».

timeEntriesLocal заполняется этим методом:

addTimeEntry () {
  let entry = {
    id: this.$store.state.UserData.timeEntriesLocal.length + 1,
    project: this.getItemById(this.$store.state.UserData.current.project_id, this.$store.state.UserData.projects),
    spentOn: new Date(),
    comment: this.comment,
    activityId: this.activityId,
    workPackage: this.getItemById(this.$store.state.UserData.current.work_package_id, this.$store.state.UserData.work_packages),
    hours: this.precisionRound(this.$store.state.UserData.duration / 60 / 60, 2),
    published: false,
    loading: false,
    infoMessage: ''
  }

  this.$store.commit('ADD_LOCAL_ENTRY', entry)
}

И, наконец, вот мутация, которую я только что использовал выше:

ADD_LOCAL_ENTRY (state, entry) {
  state.timeEntriesLocal.unshift(entry)
}

1 Ответ

0 голосов
/ 23 декабря 2018

Изменения в timeEntriesLocal не фиксируются, так как вы изменяете длину массива.Это ограничение JavaScript, описанное в разделе Common Gotchas в документации.Способ обойти это также описан в Документах Vuex :

Мутации в соответствии с Правилами реактивности Vue

Поскольку VuexСостояние хранилища делает реактивным Vue, когда мы изменяем состояние, компоненты Vue, наблюдающие за состоянием, обновляются автоматически.Это также означает, что мутации Vuex подвергаются тем же предостережениям реактивности при работе с простым Vue:

  1. Предпочитают инициализировать начальное состояние вашего магазина со всеми необходимыми полями заранее.
  2. При добавленииновые свойства объекта, вы должны либо:

    • Use Vue.set(obj, 'newProp', 123), либо
    • Заменить этот объект на новый.Например, используя синтаксис распространения объекта, мы можем написать его так: state.obj = { ...state.obj, newProp: 123 }

Итак, в вашем примере, чтобы Vue (Vuex) обнаружил этиизменения, вы можете сделать что-то вроде:

ADD_LOCAL_ENTRY (state, entry) {
    state.timeEntriesLocal.unshift(entry);
    Vue.set(state, 'timeEntriesLocal', state.timeEntriesLocal);
}
...