【Vue 开发实战】实战篇 # 40:自己封装一个支持自动校验的表单项

简介: 【Vue 开发实战】实战篇 # 40:自己封装一个支持自动校验的表单项

说明

【Vue 开发实战】学习笔记。



自定义表单控件


自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:


  • 提供受控属性 value 或其它与 valuePropName-参数) 的值同名的属性。
  • 提供 onChange 事件或 trigger-参数) 的值同名的事件。
  • 不能是函数式组件。



实现的组件效果


支持下拉选择,然后自定义校验该组件,提交能把选择的数据传递到接口02e82297064146ea9bff0542b39dabc1.png不通过:fbd02690a4e74822979e5ea7333fec66.png



编写组件

新建 ant-design-vue-pro\src\components\ReceiverAccount.vue

<template>
    <a-input-group compact>
        <a-select v-model="type" style="width: 120px;" @change="handleTypeChange">
            <a-select-option value="alipay">支付宝</a-select-option>
            <a-select-option value="bank">银行账户</a-select-option>
        </a-select>
        <a-input style="width: calc(100% - 120px);" v-model="number" @change="handleNumberChange"/>
    </a-input-group>
</template>
<script>
export default {
    props: {
        value: {
            type: Object,
        },
    },
    data() {
        const { type, number } = this.value;
        return {
            type: type || "alipay",
            number: number || ""
        };
    },
    watch: {
        value(val) {
            // 同步给 type、number
            Object.assign(this, val);
        }
    },
    methods: {
        handleTypeChange(val) {
            this.$emit("change", { ...this.value, type: val });
        },
        handleNumberChange(e) {
            this.$emit("change", { ...this.value, number: e.target.value });
        }
    },
};
</script>
<style></style>


表单的 vuex 添加状态

const state = {
    step: {
        payAccount: "kaimo313",
        receiverAccount: {
            type: "alipay",
            number: ""
        }
    }
}


在 Step1 组件里使用

<template>
    <div>
        <a-form layout="horizontal" :form="form">
            <a-form-item
                label="付款账号"
                :label-col="formItemLayout.labelCol"
                :wrapper-col="formItemLayout.wrapperCol"
            >
                <a-input v-decorator="[
                    'payAccount',
                    {
                        initialValue: step.payAccount,
                        rules: [
                            {
                                required: true,
                                message: '请输入付款账号'
                            }
                        ]
                    },
                ]" placeholder="请输入付款账号" />
            </a-form-item>
            <a-form-item
                label="收款账号"
                :label-col="formItemLayout.labelCol"
                :wrapper-col="formItemLayout.wrapperCol"
            >
                <ReceiverAccount v-decorator="[
                    'receiverAccount',
                    {
                        initialValue: step.receiverAccount,
                        rules: [
                            {
                                required: true,
                                message: '请输入收款账号',
                                validator: (rule, value, callback) => {
                                    if(value && value.number) {
                                        callback();
                                    }else{
                                        callback('收款账号没有填写');
                                    }
                                }
                            },
                        ]
                    },
                ]"/>
            </a-form-item>
            <a-form-item>
                <a-button type="primary" @click="handleSubmit">下一步</a-button>
            </a-form-item>
        </a-form>
    </div>
</template>
<script>
import ReceiverAccount from "@/components/ReceiverAccount.vue";
export default {
    data() {
        this.form = this.$form.createForm(this);
        return {
            formItemLayout:{
                labelCol: { span: 4 },
                wrapperCol: { span: 14 },
            }
        };
    },
    components: { ReceiverAccount },
    computed: {
        step() {
            return this.$store.state.form.step
        }
    },
    created() {
        console.log("this.$store---->", this.$store)
    },
    methods: {
        handleSubmit() {
            const { form, $router, $store} = this;
            form.validateFields((err, values) => {
                console.log(err, values)
                if(!err) {
                    console.log(values);
                    $store.commit({
                        type: "form/saveStepFormData",
                        payload: values
                    });
                    $router.push("/form/step-form/confirm");
                }
            })
        }
    },
};
</script>
<style></style>


目录
相关文章
|
14天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
24天前
|
JavaScript 前端开发 测试技术
组件化开发:创建可重用的Vue组件
【10月更文挑战第21天】组件化开发:创建可重用的Vue组件
24 1
|
25天前
|
JavaScript 前端开发
vue全局公共组件自动引入并注册,开发效率直接起飞!
【10月更文挑战第14天】vue全局公共组件自动引入并注册,开发效率直接起飞!
45 1
|
1月前
|
存储 前端开发 中间件
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
244 0
|
1月前
|
JavaScript 开发者
vue指令的开发看这篇文章就够了!超详细,赶快收藏!
【10月更文挑战第8天】vue指令的开发看这篇文章就够了!超详细,赶快收藏!
vue指令的开发看这篇文章就够了!超详细,赶快收藏!
|
21天前
|
JavaScript UED
"Vue实战技巧大揭秘:一招解决路由跳转页面不回顶部难题,让你的单页面应用用户体验飙升!"
【10月更文挑战第23天】在Vue单页面应用中,点击路由跳转时,默认情况下页面不会自动滚动到顶部,这可能影响用户体验。本文通过一个新闻网站的案例,介绍了如何使用Vue-router的全局前置守卫和`scrollBehavior`方法,实现路由跳转时页面自动滚动到顶部的功能,提升用户浏览体验。
56 0
|
1月前
|
存储 JSON JavaScript
Vue.js开发中基于localStorage与sessionStorage的本地存储利器:Vue-ls插件使用详解
Vue.js开发中基于localStorage与sessionStorage的本地存储利器:Vue-ls插件使用详解
47 0
|
1月前
|
设计模式 JavaScript 开发工具
Vue开发中使用好钩子方法(hook method)可以使你的代码更加模块化和可维护
Vue开发中使用好钩子方法(hook method)可以使你的代码更加模块化和可维护
18 0
|
1月前
|
JavaScript 算法 前端开发
在Vue开发中v-if指令和v-show指令的使用介绍,v-if和v-for的优先级以及使用注意事项的介绍
在Vue开发中v-if指令和v-show指令的使用介绍,v-if和v-for的优先级以及使用注意事项的介绍
17 0
|
7天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。

相关实验场景

更多