Vue.js 来自组件的Vue提交按钮未提交
我在Vue中有一个组件,我使用它来替代提交按钮。我可以向它传递一个处理程序,组件在禁用自身并将其设置为已加载状态后调用该处理程序,并且它可以在出错后恢复(再次启用自身),如果一切顺利,则显示一个漂亮的成功动画。这很有效,代码如下:Vue.js 来自组件的Vue提交按钮未提交,vue.js,vue-component,Vue.js,Vue Component,我在Vue中有一个组件,我使用它来替代提交按钮。我可以向它传递一个处理程序,组件在禁用自身并将其设置为已加载状态后调用该处理程序,并且它可以在出错后恢复(再次启用自身),如果一切顺利,则显示一个漂亮的成功动画。这很有效,代码如下: // Submit.vue <template> <button :type="type" :class="classes" :disabled="loading" @click="onClick"> <span
// Submit.vue
<template>
<button :type="type" :class="classes" :disabled="loading" @click="onClick">
<span class="flag" v-if="flag"></span>
<slot></slot>
</button>
</template>
<script>
import _ from 'lodash'
export default {
name: 'submit',
props: {
brand: {
type: String,
default: 'primary'
},
// If no handler is provided, will fallback to normal submit button
handler: {
type: Function,
required: false
},
flag: {
type: Boolean,
default: false
}
},
data () {
return {
loading: false,
success: false
}
},
computed: {
type () {
return typeof this.handler !== 'undefined' ? 'button' : 'submit'
},
classes () {
return [
`btn btn-${this.brand}`,
this.loading && !this.success ? 'loading' : null,
this.success ? 'success' : null
]
}
},
methods: {
onClick (event) {
if (this.success) {
event.preventDefault()
return
}
this.loading = true
if (typeof this.handler !== 'undefined') {
// Handler must return a Promise
this.handler.call()
.then(_.bind(() => {
this.onSuccess()
}, this))
.catch(() => {})
.then(_.bind(() => {
this.loading = false
}, this))
}
},
resetSuccess () {
this.success = false
},
onSuccess () {
this.success = true
setTimeout(this.resetSuccess, 2000)
}
}
}
</script>
//Submit.vue
从“lodash”导入
导出默认值{
名称:“提交”,
道具:{
品牌:{
类型:字符串,
默认值:“主”
},
//如果没有提供处理程序,将返回到正常的提交按钮
处理程序:{
类型:功能,
必填项:false
},
旗帜:{
类型:布尔型,
默认值:false
}
},
数据(){
返回{
加载:false,
成功:错
}
},
计算:{
类型(){
返回this.handler的类型!=“未定义”?“按钮”:“提交”
},
类别(){
返回[
`btn btn-${this.brand}`,
this.loading&!this.success?“加载”:null,
this.success?“success”:null
]
}
},
方法:{
onClick(事件){
如果(这是成功){
event.preventDefault()
返回
}
这是真的
if(this.handler的类型!==“未定义”){
//处理程序必须返回一个承诺
this.handler.call()
.然后(uu.bind(()=>{
this.onSuccess()
},本页)
.catch(()=>{})
.然后(uu.bind(()=>{
此参数为0。加载=错误
},本页)
}
},
重置成功(){
成功=错误
},
成功(){
这是真的
setTimeout(this.resetSuccess,2000)
}
}
}
如果没有传递任何处理程序,则返回到正常的提交按钮,假设您只想在提交表单时自动禁用该按钮。唯一的问题是,当我单击从组件创建的按钮时,表单未提交
我认为使用onClick
方法通过JS强制提交是相当容易的,但我想了解为什么不这样做。这是一个浏览器问题吗?安全问题?Vue问题?或者其他我错过的东西可能就在我面前
下面是一个用于快速测试的JSFIDLE:
代码并不完全相同,因为我使用的是单文件组件,但要点是相同的,并且可以很容易地观察到行为。在检查
处理程序是否存在之前,您正在将加载设置为false。由于您将按钮的disabled
属性绑定到loading
,因此您将禁用按钮并防止触发本机单击事件
检查处理程序后,只需设置load
属性:
if (typeof this.handler !== 'undefined') {
this.loading = true;
...
}
为了记录在案,我最后做了以下几点:
onClick (event) {
if (this.success) {
event.preventDefault()
return
}
this.loading = true
if (typeof this.handler !== 'undefined') {
// Handler must return a Promise
this.handler.call()
.then(_.bind(() => {
this.onSuccess()
}, this))
.catch(() => {})
.then(_.bind(() => {
this.loading = false
}, this))
} else {
this.$el.form.submit()
}
}
这允许我在单击时禁用表单并显示加载状态,但仍然强制提交。有一次它是正确的!老兄,今天早上我有一个这样的。啊,接得好。我有一种感觉,那是显而易见的。唯一的问题是,无论是否有处理程序,我都希望禁用按钮并加载类。我最终会使用JS强制提交,但你解开了这个谜:)