基于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();
        };
    
相关推荐
夏幻灵9 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
三天不学习10 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs1940511 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
雪芽蓝域zzs14 小时前
第 5 节:Marker 点击弹出 InfoWindow 信息窗口
vue.js
小宋102116 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
大包子16 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
lerhxx17 小时前
AI 应用中的上下文管理 —— 从"上下文窗口"到"分层压缩"的工程实践
前端·javascript
雪芽蓝域zzs17 小时前
第 3 节:地图点击事件,点击获取经纬度
vue.js
Mahut17 小时前
我在 Mac 上做了个本地剪辑器
javascript·架构·产品
WayneX17 小时前
开源 Vue 3 组件库 Morya UI:把组件、文档、AI 工具链一起做进一个包
前端·vue.js·前端框架