基于elelemt-ui封装一个表单

子组件

searchForm

javascript 复制代码
<template>
    <el-form
        ref="form"
        :model="value"
        :rules="rules"
        :label-width="labelWidth"
        :inline="inline"
    >
        <el-form-item
            v-for="field in fields"
            :key="field.slot"
            :label="field.label"
            :prop="field.slot"
        >
            <slot :name="field.slot">
                <el-input
                    v-if="!$slots[field.slot]"
                    v-model="formValue[field.slot]"
                    @input="updateValue(field.slot, $event)"
                />
            </slot>
        </el-form-item>
        <el-button
            type="primary"
            @click="submitForm"
        >
            搜索
        </el-button>
        <el-button @click="resetForm">
            重置
        </el-button>
    </el-form>
</template>

<script>
import {
    defineComponent, ref, watch,
} from 'vue';

export default defineComponent({
    name: 'SearchForm',
    props: {
        value: {
            type: Object,
            default: () => ({}),
        },
        fields: {
            type: Array,
            default: () => [],
        },
        rules: {
            type: Object,
            default: () => ({}),
        },
        labelWidth: {
            type: String,
            default: '100px',
        },
        inline: {
            type: Boolean,
            default: true,
        },
    },
    setup(props, { emit }) {
        const form = ref(null);
        const formValue = ref({ ...props.value });

        watch(() => props.value, (newValue) => {
            formValue.value = { ...newValue };
        }, { deep: true });

        const submitForm = () => {
            form.value.validate((valid) => {
                if (valid) {
                    emit('submit', props.value);
                } else {
                    console.log('error submit!!');
                    return false;
                }
            });
        };

        const resetForm = () => {
            form.value.resetFields();
            emit('reset');
        };

        const updateValue = (key, value) => {
            emit('input', {
                ...formValue.value,
                [key]: value,
            });
        };

        return {
            form,
            formValue,
            submitForm,
            resetForm,
            updateValue,
        };
    },
});
</script>
<style scoped>
v-deep .el-button--primary{
    margin: 0;
}
</style>

父组件

javascript 复制代码
            html
            <p>父{{ searchFormModel }}</p>
            <search-form
                ref="searchFormRef"
                v-model="searchFormModel"
                :fields="searchFromFields"
                :rules="rules"
                @submit="onSearchFormSubmit"
                @reset="onSearchFormReset"
            >
                <template #ruleId>
                    <el-select
                        v-model="searchFormModel.ruleId"
                        placeholder="请选择活动区域"
                    >
                        <el-option
                            label="区域一"
                            value="shanghai"
                        />
                        <el-option
                            label="区域二"
                            value="beijing"
                        />
                    </el-select>
                </template>
                <template #type>
                    <el-checkbox-group v-model="searchFormModel.type">
                        <el-checkbox
                            label="美食/餐厅线上活动"
                            name="type"
                        />
                        <el-checkbox
                            label="地推活动"
                            name="type"
                        />
                        <el-checkbox
                            label="线下主题活动"
                            name="type"
                        />
                        <el-checkbox
                            label="单纯品牌曝光"
                            name="type"
                        />
                    </el-checkbox-group>
                </template>
            </search-form>


    // 引入
    import searchForm from './searchForm';
    // 注册
    components: {
        searchForm,
    },
    setup() {
        const initData = reactive({
            searchFormModel: {
                categoryIds: '666',
                ruleId: '',
                type: [],
            },
            searchFromFields: [
                { label: '活动名称', slot: 'categoryIds' },
                { label: '活动区域', slot: 'ruleId' },
                { label: '活动性质', slot: 'type' },
            ],
            rules: {
                categoryIds: [
                    { required: true, message: '请输入用户名', trigger: 'blur' },
                ],
                ruleId: [
                    { required: true, message: '请选择活动区域', trigger: 'change' },
                ],
                type: [
                    {
                        type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change',
                    },
                ],
            },
            searchFormRef: null,
        });

        const onSearchFormSubmit = (form) => {
            console.log('表单提交了', form);
        };
        const onSearchFormReset = () => {
            console.log('表单重置了');
            // initData.searchFormRef.resetFields();
        };
    
相关推荐
知识分享小能手19 分钟前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程
demi_meng1 小时前
reactNative 遇到的问题记录
javascript·react native·react.js
MC丶科2 小时前
【SpringBoot 快速上手实战系列】5 分钟用 Spring Boot 搭建一个用户管理系统(含前后端分离)!新手也能一次跑通!
java·vue.js·spring boot·后端
千码君20162 小时前
React Native:从react的解构看编程众多语言中的解构
java·javascript·python·react native·react.js·解包·解构
Larry_Yanan4 小时前
QML学习笔记(四十二)QML的MessageDialog
c++·笔记·qt·学习·ui
90后的晨仔4 小时前
Pinia 状态管理原理与实战全解析
前端·vue.js
EndingCoder4 小时前
WebSocket实时通信:Socket.io
服务器·javascript·网络·websocket·网络协议·node.js
90后的晨仔4 小时前
Vue3 状态管理完全指南:从响应式 API 到 Pinia
前端·vue.js
90后的晨仔4 小时前
Vue 内置组件全解析:提升开发效率的五大神器
前端·vue.js
我胡为喜呀4 小时前
Vue3 中的 watch 和 watchEffect:如何优雅地监听数据变化
前端·javascript·vue.js