Ant Design Vue 自定义form元素formItme

1,160 阅读1分钟

今天开发过程遇到一个问题就是需要在Antd的数字输入框input-number的末尾添加如图的后缀名称。

因为在antd中最基本的input有添加后缀的标签,但是在input-number中使用没有效果,所以就需要自己手动在输入框末尾添加一个元素用来显示指定后缀。由于用的地方较多,所以想要封装成组件,但是在封装过程中,遇到了一个问题,怎么在自己封装的组件放到form表单中时,能够被表单的校验检测到。

antd官网有这么一句话,所以只需要在需要给封装组件传递数据的地方比如使用到v-model传递数据的地方,用 v-decorator代替v-model,antd的form组件就会帮我们维护数据,并且自动绑定change事件用于实时的规则校验和数据的获取。

一开时我是使用vue的v-decorator给封装组件传递数据,然后检测用户输入调用this.emit("input",val)来完成双向数据绑定,但发现调用input虽然能完成数据的双向传递,但是不够触发表单的校验,后来吧this.emit("input",val)来完成双向数据绑定,但发现调用input虽然能完成数据的双向传递,但是不够触发表单的校验,后来吧this.emit("input",val)换成this.$emit("change",val)发现数据改变表单自动进行校验,因为官网说了,会自动帮我们添加change事件

调用本身的change会触发校验规则完成表单的校验。

代码如下

  • 封装的input-number组件:
<template>
   <div class="numberWrap">
        <a-input-number
            :min="min" :max="max"
            class="number"
            v-model="number"
            :placeholder="placeholder"
        />
        <div class="numberSuffix">
            {{suffix}}
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return {
            number:""
        }
    },
    props:{
        value:{
            type:[Number,String],
        },
        min:{
            type:Number,
            default: ()=>-9999
        },
         max:{
            type:Number,
            default: ()=>9999
        },
        placeholder:{
            type:String,
            default: ()=>""
        },
        suffix:{
            type:String,
            default: ()=>""
        },
    },
    watch: {
        value:{
            immediate:true,
            handler:function(val){
                if( typeof val === "String"){
                    this.number = undefined
                }else{
                    this.number = val
                }
            }
        },
        number:{
            handler:function(val){
                this.$emit('change',val) //通过v-decorator封装的formItem默认添加change事件
            }
        }
    },
}
</script>

<style scoped>
.numberWrap{
    display: flex;
    position: relative;
}
.numberWrap .number{
    width: 100%;
    box-sizing: border-box;
    padding-right: 10%;
}
.numberWrap .numberSuffix{
    position:absolute;
    height: 100%;
    line-height: 1.9rem;
    right: 2rem;
}
</style>
  • 父组件中使用
<number-input
    :min="1" :max="10"
    suffix="分钟"
    v-decorator="[
        'run_every',
        { rules: [{ required: true, message: '请输入运行频率' }],initialValue:1 },]"
    placeholder="运行频率"
/>