Vue.js 来自组件的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

我在Vue中有一个组件,我使用它来替代提交按钮。我可以向它传递一个处理程序,组件在禁用自身并将其设置为已加载状态后调用该处理程序,并且它可以在出错后恢复(再次启用自身),如果一切顺利,则显示一个漂亮的成功动画。这很有效,代码如下:

// 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强制提交,但你解开了这个谜:)