Как правильно обновить магазин Vuex? - PullRequest
0 голосов
/ 24 сентября 2018

Я работаю над проверенной временем функцией списка Todo, используя Vue, Vuex и axios.У меня есть функция, компонентная между всем списком (TodoList) и отдельными строками (TodoRow).

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

компонент TodoList

<template>
  <dashboard-container
    :header-title="'To-Do-List'"
  >
    <div slot="action-buttons">
       <add-new-button
          v-if="!emptyTodos"
          :disabled="isCreating"
          class="pull-right"
          @click="addNewTodo"
       />
    </div>
    <transition slot="container-content" tag="div">
       <div v-if="!emptyTodos">
          {{ todos }}
          <todo-row
            v-for="(item, index) in todos"
            :key="index" :id="item.id"
            :text="item.description"
            :status="item.status"
            :completed="item.completed"
          />
       </div>
       <empty-list v-else @addClick="addNewTodo" />
    </transition>
  </dashboard-container>
</template>

<script>
import DashboardContainer from '@/components/Dashboards/DashboardContainer'
import TodoRow from '@/components/TodoList/TodoRow'
import AddNewButton from './AddNewButton'
import EmptyList from './EmptyList'
import { mapState, mapActions } from 'vuex'

export default {
   components: {
      DashboardContainer,
      EmptyList,
      TodoRow,
      AddNewButton
   },
   computed: {
      ...mapState('planProfile', {
         todos: 'todos'
      }),
      emptyTodos () {
         return this.todos.length === 0
      },
      isCreating () {
         return this.todos.some(todo => todo.status === 'created')
      }
   },
   mounted () {
      return this.dispatchAction({
         actionName: 'planProfile/getTodos'
      }).catch(err => {
         console.log('decide how to route handle errors', err)
      })
   },
   methods: {
      ...mapActions({
         dispatchAction: 'dispatchAction'
      }),
      addNewTodo () {
         this.todos.unshift({
            text: '',
            done: false,
            status: 'new'
         })
      }
   }
 }
 </script>

Вот как выглядит функция (с не сокращенным кодом) в моем браузерес несколькими предметами todo.Я выбросил задачи просто для иллюстрации исходных данных в хранилище.

enter image description here

Вот сокращенный код самого элемента задачи:

компонент TodoItem

<template>
  <div @mouseover="showActions = true" @mouseout="showActions = false">
    <div>
      <div>
        <label>
          <input
            :checked="done"
            type="checkbox"
          >
        </label>
      </div>
      <div v-show="showActions">
        <div
          v-for="action in currentActions"
          :key="action.name"
          class="action-icon pull-right"
          @click="handleActionClick(action.name)"
        >
          <svg-icon :svg-settings="action.icon" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import makeMdsIcon from '@/utils/makeMdsIcon'
import CheckboxInput from '@/components/Inputs/CheckboxInput'
import { mapActions } from 'vuex'

export default {
  components: {
    CheckboxInput
  },
  props: {
    id: {
      type: Number,
      default: null
    },
    status: {
      type: String,
      default: 'created'
    },
    completed: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      showActions: false,
      checkIcon: makeMdsIcon('check--s')
    }
  },
  computed: {
    done () {
      return this.completed
    },
    isCreating () {
      return this.status === 'new' || this.status === 'updating'
    },
    currentActions () {
      const actions = {
        new: [{
          name: 'save',
          icon: this.checkIcon
        }]
      }

      return actions[this.status]
    }
  },
  created () {
    if (this.completed) {
      this.status = 'done'
    }
  },
  methods: {
    ...mapActions({
      dispatchAction: 'dispatchAction'
    }),
    saveTodo () {
      this.status = 'created'
      return this.dispatchAction({
        actionName: 'planProfile/createTodo',
        data: {
          description: this.text
        }
      }).catch(err => {
        console.log('decide how to route handle errors', err)
      })
    },
    handleActionClick (actionName) {
      const handlers = {
        save: this.saveTodo
      }

      const currentHandler = handlers[actionName]

      return currentHandler()
    }
  }
}
</script>

Когда вызывается метод saveTodo и вызывается базовое действие planProfile/updateStatusTodo на уровне хранилища Vuex, сохранение сохраняется на бэкэнде иЯ могу это проверить, когда освежусь.Однако, как видно из компонента TodoList, хранилище не обновляется, когда это происходит:

Сокращенное хранилище Vuex

import todoService from '@/services/todoService'

const state = {
  todos: []
}

const actions = {
  createTodo: {
    handler ({ commit }, payload = []) {
      const { description } = payload
      return todoService.createTodo({ description })
        .then(todoData => {
          return commit('addTodo', todoData)
        })
    }
  }
}

const mutations = {
  addTodo (state, payload) {
    /* The line below is just for demonstrative purposes for this question */
    state.todos = state.todos.push({id: 9999, description: 'this is mock data for SO', completed: false})
  }
}

export default {
  namespaced: true,
  state,
  actions,
  mutations
}

Почему магазин не работаетобновляется, когда addTodo вызывается на уровне магазина Vuex?Я уже проверил процедуру для других операций задачи (например, удаления задачи), в результате чего я удаляю задачу, и эта информация мгновенно передается компоненту TodoList, почему то же самое не происходит при создании новых задач?

Поток:

  1. Прямо перед тем, как я собираюсь сохранить, нажав на галочку рядом с первым элементом:

enter image description here

После щелчка элемент был сохранен в бэкэнде (что я могу проверить, обновив), но его нет в хранилище, поскольку задачи не изменились (а также путем проверки хранилища Vuex в консоли разработчика Chrome).

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...