如何正确更新Vuex存储?

时间:2018-09-24 16:43:16

标签: javascript vue.js vuejs2 vuex

我正在使用Vue,Vuex和axios开发历史悠久的Todo列表功能。我将功能分为 整个列表本身(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>

这里是带有一些待办事项的功能(带有非缩写代码)的外观。我只把待办事项丢了 轻松显示商店中的原始数据。

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方法并在Vuex存储级别上调用基础planProfile/updateStatusTodo操作时,保存将一直保存在后端,刷新后可以验证这一点。但是,从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
}

为什么在Vuex商店级别调用addTodo时商店没有更新?我已经验证了程序 用于其他待办事项操作(例如删除待办事项),从而删除待办事项,并且此信息会立即传达给 TodoList组件,为什么创建新的待办事项不会发生相同的事情?

流量:

  1. 在我要保存之前,通过单击第一项旁边的对勾标记:

enter image description here

  1. 单击后,项目已保存在后端(我可以通过刷新来验证),但是由于待办事项未更改(并且通过在Chrome开发者控制台中检查Vuex商店),因此该项目不在商店中。

enter image description here

0 个答案:

没有答案