基于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();
        };
    
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
咖啡教室12 小时前
前端开发日常工作每日记录笔记(2019至2024合集)
前端·javascript
咖啡教室12 小时前
前端开发中JavaScript、HTML、CSS常见避坑问题
前端·javascript·css
市民中心的蟋蟀15 小时前
第五章 使用Context和订阅来共享组件状态
前端·javascript·react.js