Удаление данных Vuex

Я недавно начала изучать Vuex и сейчас делаю небольшое приложение календарь. Хочу удалить данные и чтобы это все было реактивно.

Мой компонент

...mapMutations(['deletePost']),
deleteTask(todo) {
  this.$store.commit('deletePost', todo);
}

сама мутация

deletePost(state,post){
   fetch(postsUrl + post.id, {
        headers: {
            'content-type': 'application/json',
        },
        method: 'POST',
        body: JSON.stringify(post),
    })
        .then(() => state.post.splice(state.post.findIndex(p => p.id === post.id), 1))
    }

state:{
    posts:[]
},

Подскажите как это сделать(


Ответы (2 шт):

Автор решения: Eugene X

Дело в том что vue Observer не подписывается на значения массива. Он может быть подписан только на изменение ключей в data. После запроса тебе надо пнуть весь массив целиком, тогда Vue поймёт что пора прорисоваться.

Как пнуть Observer по зад, описано вот в этом ответе. https://stackoverflow.com/questions/48984877/vuejs-manually-trigger-an-update-into-observed-object-array

→ Ссылка
Автор решения: Mikalai Parakhnevich

Cостояние хранилища Vuex — это реактивная переменная Vue, при возникновении мутации, зависящие от этого состояния компоненты Vue обновляются автоматически. Кроме того, это значит, что мутации Vuex имеют те же самые подводные камни, что и реактивность в обычном Vue.

Учитывая это, получается, что vuex по умолчанию, все что объявлено в state делает реактивным (это не значит, что нельзя добавить реактивные данные после инициализации), следуя правилам замены в массиве, вам достаточно, используя один из изменяемых или неизменяемых методов для массива, внести изменения в данные из state, чтобы компоненты, которые используют эти данные получили актуальное состояние vuex.

Приведу небольшой пример для наглядности (обратите внимание, что данные из state в компоненте используются через getters, получаются данные с сервера через actions, это дает возможность использовать асинхронность, в мутациях использовать таковую нет возможности, потому что мутации должны быть синхронными, чтобы быстро вносить изменения в state, после получения ответа от сервера - производятся мутации, чтобы синхронизировать состояние с сервера с состоянием vuex. Пример не является лучшей практикой, но хорошо демонстрирует некоторые возможности vuex:

const {
  mapGetters,
  mapMutations,
  mapActions,
} = Vuex;

const store = new Vuex.Store({
  state: {
    posts_data: [],
  },
  getters: {
    posts: (state) => state.posts_data
  },
  mutations: {
    changePosts(state, posts) {
      state.posts_data = posts
    },
    deletePost(state, id) {
      state.posts_data = state.posts_data.filter((post) => post.id !== id)
    },
  },
  actions: {
    async findPosts({
      commit
    }, data) {
      const posts = await fetch('http://jsonplaceholder.typicode.com/posts?_limit=5')
        .then(response => response.json())
        .then(json => commit('changePosts', json))
        .catch(e => console.error(e))
      return posts
    },
    async deletePostDb({
      commit
    }, post_id) {
      const post = await fetch(`http://jsonplaceholder.typicode.com/posts/${post_id}`, {
          method: 'DELETE',
        })
        .then(response => response.json())
        .then((json) => {
          commit('deletePost', post_id)
        })
        .catch(e => console.error(e))
      return post
    }
  }
})

new Vue({
  el: '#app',
  store,
  data: () => ({}),
  computed: {
    ...mapGetters(['posts'])
  },
  methods: {
    ...mapActions(['findPosts', 'deletePostDb']),
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app">
  <div>
    <ul>
      <li v-for="post in posts" :key="post.id">
        {{post.id}} - {{ post.title }}
        <button type="button" @click="deletePostDb(post.id)">Удалить</button>
      </li>
    </ul>
    <button type="button" @click="findPosts">Найти посты</button>
  </div>

</div>

→ Ссылка