Javascript Vue JS在出现错误时更改提交按钮
使用Vuex,我有一个表单,当单击按钮时(@click=“loader(true)”)会发送到加载程序,将加载更改为true,然后将带有Bulma CSS的is-loading类设置为true('is-loading':$store.state.index.loading) 然后,如果表单为空且有错误,我将从服务器接收错误。title,这对输入很好,但是如果有错误,我如何将is loading类设置为false (如果运行该代码段,它将无法工作)Javascript Vue JS在出现错误时更改提交按钮,javascript,vue.js,vuex,Javascript,Vue.js,Vuex,使用Vuex,我有一个表单,当单击按钮时(@click=“loader(true)”)会发送到加载程序,将加载更改为true,然后将带有Bulma CSS的is-loading类设置为true('is-loading':$store.state.index.loading) 然后,如果表单为空且有错误,我将从服务器接收错误。title,这对输入很好,但是如果有错误,我如何将is loading类设置为false (如果运行该代码段,它将无法工作) export const state=()=>(
export const state=()=>({
加载:错误
});
导出常量突变={
加载器(状态、值){
state.loading=值;
}
}
{{errors.title[0]}
邮递
从“vuex”导入{mapstations,};
方法:{
…地图突变({
加载器:“索引/加载器”
})
}
问题是关于使用…MapTranslations
,但如果有人想添加业务逻辑,建议使用mapAction
和mapState
。我将解释如何使它与mapAction
和mapState
一起工作,因为调用API可能涉及在应用程序中使用业务逻辑。否则,我会说,除了通知应用程序的其他部分正在加载之外,为什么还要麻烦使用VueX;)。话虽如此,这是我的答案
使用…mapState
可以得到您要搜索的内容,即计算出的
状态的反应性。这尤其会在调用操作期间发生。然后,操作将发生更改,或者在VueX中我们称之为commit
的状态(请参阅文档:)
让我们将您的代码更改为具有名称空间的模块,然后在vue中使用该模块(如果应用程序很大,我会这样做,否则使用变异或根本不使用VueX也可以实现这一点):
对于您的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>
<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>
考虑到您正在某处进行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>
{{errors.title[0]}
邮递
首先,不需要在全局状态(Vuex)中设置仅本地需要的状态(加载)。因此,典型用法如下所示:
<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>
<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>
{{errors.title[0]}
邮递
导出默认值{
...
数据(){
返回{
...
新标题:'',
孤岛加载:false,
答复:空
}
},
方法:{
异步postForm(){
试一试{
this.isload=true//首先,将状态更改为true
const{data}=wait axios.post('someurl',{title:this.newTitle})//然后等待某个异步调用
this.response=data//保存响应
}捕捉(错误){
//如果出现错误,请在此处进行处理
}最后{
this.isload=false//但始终将状态更改回false
}
}
}
}
如果您像这样使用vuex。我猜你误解了vuex。因为您可以对局部变量使用,并且可以检查api结果。如果您想要单独的api请求,您必须在方法中映射action,在Computed中映射Getter您可能需要在这种情况下使用一个操作来切换状态的值。根据服务器的响应,将
加载为false。请不要引用我的话,但应该是类似于this.$store.commit的内容('loader',false)
。哦,等等。我看错了。做一些验证或者试试{}catch{}
在您的postThis
方法中。如果您可以向我们公开该方法,我们可以尝试进一步提供帮助。postThis如果使用承诺,您应该对逻辑和突变、状态、操作的用法很好。如果您有业务逻辑,则直接使用突变是不好的。我实际上会将业务逻辑放在您的操作和n使用commit管理所有状态。commit(加载)然后commit(失败)或commit(completedWithSuccess)。然后您只有一个方法可调用。在这取决于您之后,您可以正确使用vuex;)是的,使用commit('loader',true)将突变移动到操作中是有意义的但是,如果你没有其他的需要,直接使用变异也没有什么错,只是改变状态,这显然是一个例子,而不是把完整的操作方法放到mdn文档中去尝试。。。catch和async/waiting使用实际代码提出另一个问题,这是一个不可读的混乱。您不必映射任何可以直接调用突变或直接调用状态的内容,map是一个扩展运算符,当您有多个操作或getter时使用,也许你误解了Vuex的灵活性,如果你检查一下,你就会明白什么是动作和变异