Я работаю над проверенной временем функцией списка 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.Я выбросил задачи просто для иллюстрации исходных данных в хранилище.
Вот сокращенный код самого элемента задачи:
компонент 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, почему то же самое не происходит при создании новых задач?
Поток:
- Прямо перед тем, как я собираюсь сохранить, нажав на галочку рядом с первым элементом:
После щелчка элемент был сохранен в бэкэнде (что я могу проверить, обновив), но его нет в хранилище, поскольку задачи не изменились (а также путем проверки хранилища Vuex в консоли разработчика Chrome).