vue 封装Form 表单组件

基于element-plus封装一个表单组件

在components目录下新建一个Form.vue

javascript 复制代码
<template>
    <section class="form-wrap">
        <el-form 
	        :model="formDatas" 
	        label-width="100" 
	        label-position="right" ref="form" 
	        :rules="rules">
            <el-row :gutter="8">
                <template v-for="item in propList" :key="item.id">
                    <el-col :span="8">
                        <el-form-item 
	                        v-if="item.show" 
	                        :key="item.id" 
	                        :prop="item.prop" 
	                        :label="item.label">
                            // input
                            <el-input 
	                             v-else="item.type == 'input'"
	                             v-model="formDatas[item.prop]"
	                            :placeholder="item.placeholder" 
	                            :disabled="item.disabled" 
	                            :style="{ width: item.width }"
	                            clearable>
	                         </el-input>
                            // select
                            <el-select 
                            	v-if="item.type == 'select'"
                                v-model="formDatas[item.prop]"
                                :placeholder="item.placeholder" 
                                :style="{ width: item.width }" 
                                clearable>
                                <el-option 
	                                v-for="option in item.options" 
	                                :label="option.label" 
	                                :value="option.value"
                                    :key="option.value">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </template>
            </el-row>
            // 插槽
            <slot></slot>
        </el-form>
    </section>
</template>

<script setup>
import { ref, reactive, toRefs, inject, onMounted } from 'vue'
import { ElMessage } from 'element-plus'

const form = ref(null)

const emits = defineEmits(['close'])

const data = reactive({
    formDatas: {}
})

// 因为是在Dialog组件中的 form 所以通过依赖注入的方式通信
// 解构注入的属性
const { title, formData, addData } = inject('formObj')

onMounted(() => {
    const dataForm = formData
    formDatas.value = dataForm
})

// 定义表单属性校验
const rules = reactive({
    name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
    username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
    phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }]
})

const { formDatas } = toRefs(data)
// 表单验证
const formValidate = async () => {
    await form.value.validate((valid, fields) => {
        if (valid) {
            const editFormData = formDatas.value
            addData(editFormData)
            if (title === '编辑') {
                ElMessage({
                    message: '修改成功',
                    type: 'success',
                })
            } else {
                ElMessage({
                    message: '新增成功',
                    type: 'success',
                })
            }
            emits('close')
        }
    })
}

function resetForm() {
    form.value.resetFields()
}

defineProps({
    propList: Array,
    formDatas: Object
})

defineExpose({
    formValidate,
    resetForm
})
</script>

<style lang="scss" scoped>
.form-wrap {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    padding: 5px;
}
</style>
相关推荐
算是难了10 小时前
Nestjs学习总结_3
前端·typescript·node.js
RONIN10 小时前
VUE开发环境配置基础(构建工具→单文件组件SFC→css预处理器sass→eslint)及安装脚手架
vue.js
yogalin199310 小时前
如何实现一个简化的响应式系统
前端
kyriewen1110 小时前
项目做了一半想重写?这套前端架构让你少走3年弯路
前端·javascript·chrome·架构·ecmascript·html5
HashTang10 小时前
我用 Cloudflare Workers + GitHub Actions 做了个 2.5 刀/月的 AI 日报,代码开源了
前端·ai编程·aiops
RONIN10 小时前
vue2、vue3区别之混入mixins和过滤器filter
vue.js
老王以为10 小时前
前端重生之 - 前端视角下的 Python
前端·后端·python
饭后一颗花生米10 小时前
2026 AI加持下前端学习路线:从入门到进阶,高效突破核心竞争力
前端·人工智能·学习
五号厂房10 小时前
TypeScript 类型导入详解:import type 与 import {type}
前端
RONIN10 小时前
属性透传attribute、vue实例对象方法$nextTick()、虚拟dom与浏览器渲染机制
vue.js