Vuex 在提交时更新视图

Vuex update view on commit

我是 Vuex js 和商店的新手。

我有以下store.js

import Vuex from 'vuex'
import Vue from 'vue'
import axios from 'axios';


Vue.use(Vuex)

export const store = new Vuex.Store({
        state: {
            pacientes: []
        },
        mutations: {
            getPacientes() {
                axios.get('http://slimapi/api/pacientes')
                .then(response => {
                    this.state.pacientes = response.data
                })
                .catch(e => {
                    console.log(e)
                })  
                }
        }

});

然后我在调用此函数的模态(v-dialog)上单击按钮时执行提交

 agregarTurno()
  {
    axios.post('/api/pacientes/add', {

        ...

     }).then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });

               this.$store.dispatch('fetchPacientes')
  }

然后我有我的 turno.vue(将其视为 app.vue),我在其中检索商店的状态。 然而,当提交后,视图上的状态并没有更新!

我正在尝试在状态更改时更新视图!

turno.vue

export default {
  name: 'turno',
  data () {
    return {
      pacientes: this.$store.state
      }
    },
    created() {
      this.$store.commit('getPacientes')
    },
    mounted() {
      this.$store.commit('getPacientes')
    },
  components: {
    tarjetaTurno,
    bottomNav,
    modalTurno 
  }
}

我已经准备好一些帖子,其中一些讨论使用计算 属性 但我不明白如何以及是否需要在每次状态更改时更新视图.

谢谢大家!



编辑已解决

store.js

export const store = new Vuex.Store({
        state: {
            pacientes: []
        },
        mutations: {
            setPacientes(state, payload) {
                state.pacientes = payload.pacientes
            }
        },
        actions: {
            fetchPacientes({commit}) {
                axios.get('http://slimapi/api/pacientes')
                     .then(response => {
                        commit('setPacientes', {pacientes: response.data}); //After getting patients, set the state
                     })
                     .catch(e => {
                        console.log(e)
                     }) 
            },
            addPacientes(context){
                axios.post('/api/pacientes/add', {
                    nombre: "test",
                    apellido: "test",
                    edad: "test",
                    peso_inicial:"test",
                    patologia:"test"
                   }).then(function (response){
                        context.dispatch('fetchPacientes'); //After adding patient, dispatch the fetchPatient to get them and set state 
                    })
                    .catch(function (error) {
                      console.log(error);
                    });          
            }
        }
});

调用添加患者函数的组件模态:

  agregarTurno()
  {
    this.$store.dispatch('addPacientes');
  }

Turno.vue (root) 状态改变时更新的人

export default {
  name: 'turno',
  data () {
    return {
      pacientes: this.$store.state
      }
    },
    created() {
      this.$store.dispatch('fetchPacientes')
    },

你的问题是突变是同步的,而你在你的突变(异步)中进行 axios.get 调用。

您应该在您的组件或 vuex action:

中处理 axios.get

使用 vuex 操作处理 axios.get() 调用:

export const store = new Vuex.Store({
  state: {
    pacientes: []
  },
  mutations: {
    setPacientes(state, payload) {
      // note how we don't call this.state.
      // state comes as param.
      state.pacientes = payload.pacientes;
    },
  actions: {
    fetchPacientes(context){
      axios.get('http://slimapi/api/pacientes')
      .then(response => {
          context.commit('setPacientes', {pacientes: response.data});
      })
      .catch(e => {
          console.log(e)
      }) 
    }
  }
  }
});

然后在你的组件中:

agregarTurno() {
  // commit is for mutations, while dispatch is for actions
  this.$store.dispatch('fetchPacientes')
}

避免 vuex 操作:

您可以在您的组件中进行 api 调用,然后 commit 变更:

agregarTurno() {
  axios.get('http://slimapi/api/pacientes')
  .then(response => {
    this.$store.commit('setPacientes', {pacientes: response.data});
  })
  .catch(e => {
      console.log(e)
  })
}

但是,如果多个组件将进行此 api 调用,您可以通过将其放在 vuex 操作中来避免代码重复。

我认为将这种异步代码作为 vuex 操作放在商店中通常被认为是最佳实践。

您粘贴的代码中存在一些问题

您不需要在 created()mounted() 挂钩中分派一个动作。我想 created() 是最好的选择。

为了让你的组件对商店做出反应,设置一个引用商店中 pacientesdata() 成员就可以了,我会这样做:

data () {
  return {
    pacientes: this.$store.state.pacientes
    }
  },

现在,如果您的组件会使用商店的很多东西,我会设置一个 vuex getter