【问题标题】:Vuex update view on commitVuex 在提交时更新视图
【发布时间】:2019-01-04 20:36:18
【问题描述】:

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

【问题讨论】:

  • 您的突变方法 getPacientes 必须接收状态对象作为参数查看教程:vuex.vuejs.org/guide/getters.html#property-style-access 并且请不要在您的代码中将葡萄牙语与英语混用是一种不好的做法 :) 是的,我是也是巴西人!希望能帮到你!
  • @RamonSchmidt 谢谢!,我已经阅读了文档,但我不明白这种处理状态的方式。谢谢!

标签: javascript vue.js vuejs2 vuex vuex-modules


【解决方案1】:

您的问题是突变是同步的,而您在突变内部进行 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() 是最好的选择。

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

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

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

【讨论】:

  • 非常感谢!所以每次我想处理商店的突变状态时,我都必须将状态作为参数传递?感谢代码调试
  • 是的,mutations 总是将state 作为第一个参数,而 action 总是将 store 作为第一个参数。
  • 你的意思是“行动总是需要上下文”吗?
  • 我在示例中调用了第一个参数context,因为这是标准方式。然而,它只是一个名字。重要的是,当您 dispatch 来自组件的操作时,例如传递患者列表,vuex 引擎将调用该操作,其中商店作为第一个参数,患者列表作为第二个参数。因此,您可以通过调用 context.commit 从操作中调用突变。但是context 只是一个参数名称,您可以将其更改为 'store'、'almacen' 或任何您喜欢的名称:第一个参数将始终是 vuex 存储本身。
  • 嘿@Sergeon,在我的turno.vue 中哪个是保持视图更新的最佳实践?在data() 我返回state,在created()dispatch the action,同样在mounted()?谢谢!
猜你喜欢
  • 2019-08-08
  • 2020-05-30
  • 1970-01-01
  • 2021-02-05
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
  • 2011-07-09
相关资源
最近更新 更多