[Vuejs]-Vue component doesn't update when state in store is updated

0đź‘Ť

A way to solve this can be to create what I like to call a refresh() method.

Basically, you will have a local list of todos in your data() method, the refresh() method will load all the todos from the store into the local todos list, every time you do an action, such as creating, deleting, or updating, you would call the refresh method to re-load the list for you.

So, in your TodoList.vue:

<template>
    <todo-item v-for="todo in todosFiltered" :key="todo.id"></todo-item>
</template>

<script>
export default {
    data() {
        return {
            // Where we store the local list of Todos 
            // so the component will react when we do something to it
            todosFiltered: []
        }
    },
    methods {
        refresh() {
            // Get the todo list from the store.
            // which in turn will trigger a change event so the component
            // react to what we did.
            this.todosFiltered = this.$store.getters.todosFiltered;
        },
        addTodo() {
            this.$store.dispatch('addTodo').then(() => {
                // Refresh the list after adding a new Todo
                this.refresh();
            })
        },
        updateTodo() {
            this.$store.dispatch('updateTodo').then(() => {
                // Refresh the list after updating a Todo
                this.refresh();
            })
        },
        deleteTodo() {
            this.$store.dispatch('deleteTodo').then(() => {
                // Refresh the list after deleting a Todo
                this.refresh();
            })
        }
    },
    created() {
        this.$store.dispatch('loadTodos').then( () => {
            // Refresh the list when first loaded after the Todos been saved in Vuex
            this.refresh();
        })
    }
}
</script>

Don’t actually delete what you already have and replace it with
this, just apply what’s here to your code.

👤Ali Almoullim

-1đź‘Ť

The problem is using a $store.getter on the v-for loop.
Try the following:

  1. Set your computed to

    todos() {
    return this.$store.todos;
    }

  2. Change your v-for loop to use todo in todos

  3. Add a v-if condition to the loop like v-if=”filtered(todo)”
  4. Create a new method called filtered (or whatever you prefer), and add your “filteredTodos” logic there, returning true/false as needed
  5. If you need to share this code, you can always use a mixin and share it between your components

Hope this works for you

👤Marina Mosti

Leave a comment