#javascript #vue.js #nuxt.js #vuex
Вопрос:
У меня есть Vuejs/Nuxtjs
приложение, в котором мне нужно получить доступ Vuex
к магазину state
после того, как он был изменен Vuex action
. В настоящее время, когда я пытаюсь запустить action
, а assignment
затем получаю старое состояние, а не то, которое было обновлено позже action
.
Как заставить код дождаться action
завершения, а затем выполнить следующую инструкцию? Ниже приведен код, который у меня есть в настоящее время: Компонент Vuejs:
<template>
<div>
<input v-model="formData.value" type="text">
<button @click="performAction">
Click Me
</button>
</div>
</template>
<script>
export default {
data () {
return {
formData: {
value: '',
returnValue: ''
}
}
},
methods: {
performAction () {
// Set the value within the Vuex Store
this.$store.commit('modules/DataStore/populateData', this.formData.value)
// Perform the Action
this.$store.dispatch('modules/DataStore/getData').then(() => {
console.log("AFTER COMPLETE ACTION")
})
// Assign the update value to the variable
this.formData.returnValue = this.$store.state.modules.DataStore.data
}
}
}
</script>
<style>
</style>
Магазин Vuex:
export const state = () => ({
data:''
})
export const mutations = {
populateData (state, data) {
state.data = data
}
}
export const actions = {
getData ({ commit, state, dispatch }) {
const headers = { 'Content-Type': 'application/json' }
this.$axios
.post('/getUrlData', state.data, { headers })
.then((response) => {
console.log("WITHIN RESPONSE")
commit('populateData',response.data)
})
.catch((error) => {
commit('populateData', 'Unable to obtain data, Error : ' error)
})
}
}
Ниже приведены вещи, которые я пробовал, и в данный момент ничего не работает:
- Я попробовал эту
.then()
функцию. - Я пытался
Async
,await
но и то и другое не работает
Любые предложения будут по-настоящему оценены. Заранее спасибо.
Комментарии:
1. Ваш код не будет ждать завершения асинхронной операции. Попробуйте добавить follwing
this.formData.returnValue = this.$store.state.modules.DataStore.data
внутри вычисляемого свойства.2. попробовал асинхронность и ожидание, но оба не работают — что именно вы пробовали? Предположительно, они не работали, потому что использовались неправильно. В настоящее время вы вообще не связываете обещания по цепочке, поэтому код, очевидно, не будет их ждать.
Ответ №1:
Вам нужно вернуть свое обещание в свой, если вы хотите связать его в цепочку в вызывающем методе. напр.:
getData ({ commit, state, dispatch }) {
const headers = { 'Content-Type': 'application/json' }
return this.$axios // now this promise will be returned and you can chain your methods together
.post('/getUrlData', state.data, { headers })
.then((response) => {
console.log("WITHIN RESPONSE")
commit('populateData',response.data);
return response.data; //this will allow you do send the data through to the next Then() call if you want to
})
.catch((error) => {
commit('populateData', 'Unable to obtain data, Error : ' error)
})
}
Этой ситуацией намного проще управлять с помощью ИМО с асинхронным ожиданием. Это становится:
export const actions = {
async getData ({ commit, state, dispatch }) {
const headers = { 'Content-Type': 'application/json' }
const response = await this.$axios.post('/getUrlData', state.data, { headers });
console.log("WITHIN RESPONSE")
commit('populateData',response.data);
}
}
и
methods: {
async performAction () {
// Set the value within the Vuex Store
this.$store.commit('modules/DataStore/populateData', this.formData.value)
// Perform the Action
await this.$store.dispatch('modules/DataStore/getData');
console.log("AFTER COMPLETE ACTION");
// Assign the update value to the variable
this.formData.returnValue = this.$store.state.modules.DataStore.data
}
}
Комментарии:
1. Большое спасибо за ответ. Это работает, как и ожидалось, но с одной небольшой проблемой. Когда я присваиваю значение своей переменной компонента
this.formData.returnValue = this.$store.state.modules.DataStore.data
, я получаю сообщение об ошибкеclient.js:227 Error: [vuex] do not mutate vuex store state outside mutation
. Если я прокомментирую эту строку, то все будет работать так, как ожидалось. Я хотел знать, как я могу временно назначить состояние vuex моей переменной компонента?
Ответ №2:
Вы можете создать геттер в vuex :
export const getters = {
getData: (state) => state.data,
};
export const actions = {
async setData ({ commit }, data) {
const headers = { 'Content-Type': 'application/json' }
await this.$axios
.post('/getUrlData', data, { headers })
.then((response) => {
console.log("WITHIN RESPONSE")
commit('populateData',response.data)
})
.catch((error) => {
commit('populateData', 'Unable to obtain data, Error : ' error)
})
}
}
затем в компоненте вы можете сопоставить получатели и действия и вызвать их :
import { mapGetters, mapActions } from 'vuex'
computed: {
...mapGetters(['getData']),
},
methods: {
...mapActions(['performAction']),
async performAction() {
await this.setData(this.formData.value)
this.formData.returnValue = this.getData
}
}