使用Vuex,我有一种形式,当单击按钮时(@ click =“ loader(true)”)发送到loader突变以将load更改为true,然后将Bulma CSS的is-loading类设置为true (“正在加载”:$ store.state.index.loading)。
如果表单为空,且有errors.title,那么我会从服务器收到错误,这在输入中可以正常工作,但是如果出现错误,我该如何将is-loading类设置为false?
(如果运行该代码段,则该代码段将不起作用)
export const state = () => ({
loading: false
});
export const mutations = {
loader(state, value) {
state.loading = value;
}
}
<form @submit.prevent="postThis">
<div class="field">
<div class="control">
<input class="input" :class="{ 'is-danger': errors.title }" type="text" id="title" placeholder="I have this idea to..." autofocus="" v-model="newTitle">
</div>
<p class="is-size-6 help is-danger" v-if="errors.title">
{{ errors.title[0] }}
</p>
</div>
<div class="field">
<div class="control">
<button @click="loader(true)" type="submit" :class="{'is-loading' : $store.state.index.loading }">
Post
</button>
</div>
</div>
</form>
<script>
import {mapMutations,} from 'vuex';
methods: {
...mapMutations({
loader: 'index/loader'
})
}
</script>
答案 0 :(得分:2)
问题是有关使用...mapMutations
的问题,但是如果有人想添加业务逻辑,则建议使用mapAction
和mapState
。我将说明如何使其与mapAction
和mapState
一起使用,因为调用API可能涉及在应用程序中使用业务逻辑。否则,我会说,为什么除了通知应用程序的其他部分正在加载之外,您还要使用VueX?话虽如此,这是我的答案。
使用...mapState
,您可以搜索到computed
状态的状态。尤其是在调用动作期间,会发生这种情况。然后动作将发生变化,或者我们在VueX中称为状态的commit
(请参阅doc:https://vuex.vuejs.org/guide/state.html)
让我们将您的代码更改为具有名称空间的模块,然后在您的vue中使用该模块(如果应用程序很大,我会这样做,否则可以通过使用突变或不使用VueX来实现相同的功能全部):
const LOADING_STATE = 'LOADING_STATE'
export default {
namespaced: true, // Read the doc about that
state: {
loaded: false
},
mutations: {
[LOADING_STATE]: function (state, isLoading) {
state.loading = isLoading
}
},
actions: {
setLoading ({ commit }, isLoading) {
commit(LOADING_STATE, isLoading)
}
}
}
对于您的 vue 文件,其中包含模板和操作。看起来像这样:
<script>
import { mapAction, mapState } from 'vuex'
exports default {
computed: {
...mapState({
// Here you could even have the full computation for the CSS class.
loading: state => state.loadingModule.loading,
// Like this... or you could use the getters that VueX does (search in the documentation since it's out of the scope of your question)
loadingCss: state => { return state.loadingModule.loading ? 'is-loading' : '' }
})
},
methods: {
// Usage of a namespace to avoid other modules in your VueX to have the same action.
...mapActions(['loadingModule/setLoading']),
}
}
</script>
关于html模板,您将能够调用方法this['loadingModule/setLoading'](true)
或false
,然后您可以响应的属性将被“加载”。
在使用post
或get
或任何其他HTTP Rest调用期间,使用Promise时,请不要忘记上下文。如果您使用的是Axios,请在您的VueJs上下文中注册后,我会做
this.$http.get('/my/api')
.then(response => {
// ... some code and also set state to ok ...
})
.catch(e => {
// set state to not loading anymore and open an alert
})
考虑到您正在某个地方进行HTTP(S)调用,现在就完成您的代码。
<form @submit.prevent="postThis">
<div class="field">
<div class="control">
<!-- Here I would then use a computed property for that class (error). I would even put the a template or a v-if on a div in order to show or not all those html elements. That's you're choice and I doubt this is your final code ;) -->
<input class="input" :class="{ 'is-danger': errors.title }" type="text" id="title" placeholder="I have this idea to..." autofocus="" v-model="newTitle">
</div>
<p class="is-size-6 help is-danger" v-if="errors.title">
{{ errors.title[0] }}
</p>
</div>
<div class="field">
<div class="control">
<button @click="['loadingModule/setLoading'](true)" type="submit" :class="{'is-loading' : loading }">
Post
</button>
</div>
</div>
</form>
答案 1 :(得分:0)
首先,无需在全局状态(Vuex)中仅具有本地所需的状态(正在加载)。因此,典型用法如下:
<template>
<form>
<div class="field">
<div class="control">
<input
class="input" :class="{ 'is-danger': errors.title }"
type="text"
id="title"
placeholder="I have this idea to..."
autofocus=""
v-model="newTitle"
>
</div>
<p class="is-size-6 help is-danger" v-if="errors.title">
{{ errors.title[0] }}
</p>
</div>
<div class="field">
<div class="control">
<button
@click="postForm"
:class="{'is-loading': isLoading }"
>
Post
</button>
</div>
</div>
</form>
</template>
<script>
export default {
...
data () {
return {
...
newTitle: '',
isLoading: false,
response: null
}
},
methods: {
async postForm () {
try {
this.isLoading = true // first, change state to true
const { data } = await axios.post('someurl', { title: this.newTitle }) // then wait for some async call
this.response = data // save the response
} catch(err) {
// if error, process it here
} finally {
this.isLoading = false // but always change state back to false
}
}
}
}
</script>
答案 2 :(得分:-1)
如果您使用vuex这样的话。我想你误会了Vuex。因为您可以使用局部变量,并且可以检查api结果。如果您需要单独的api请求,则必须在方法中使用mapAction并在Computed中使用mapGetters