0

我是 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')
    },
4

1 回答 1

2

您的问题是突变是同步的,而您在axios.get突变内部进行调用(这是异步的)。

您应该axios.get在组件或vuex 操作中处理:

使用 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()是最好的选择。

为了使您的组件对商店做出反应,设置一个data()引用商店中的成员是可以的pacientes,我会这样做:

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

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

于 2018-07-27T17:27:52.067 回答