vue3+elementPlus+ts封装form表单组件
- 1、前言
- 2、form表单组件部分
- 2.1、组件目录结构如下图所示
- 2.2、各个文件代码如下
- Item.vue文件
- config.ts文件
- index.vue文件
- 3、组件使用例子如下
1、前言
因近期项目中涉及大量的表单字段(一个表单多达40-50个字段)的页面现象存在,因此为了减少大量CV操作(当然封装了之后也少不了CV)和避免自己在写的时候迷失在代码块中,故封装了该form表单组件,下面将会贴出简化版代码(仅供参考)。
2、form表单组件部分
2.1、组件目录结构如下图所示
2.2、各个文件代码如下
Item.vue文件
<template>
<component :is="getComponent" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { formItemMap } from '../config';
const props = defineProps({
itemProps: {
type: Object,
default: () => ({}),
},
modelValue: {
type: [String, Number, Object, Array],
},
})
const emits = defineEmits(['changeVal'])
const getComponent = () => {
return h(formItemMap.get(props.itemProps.type), {
modelValue: props.modelValue,
...props.itemProps.props,
['onUpdate:modelValue']: (val: any) => {
emitChange({
key: props.itemProps,
value: val,
});
},
});
};
const emitChange = (obj: object) => {
emits('changeVal', { ...obj });
};
</script>
<style lang="scss" scoped></style>
config.ts文件
import type { VNode } from 'vue'
//基础组件类型
type formItemType = 'input' | 'datePicker'
//表单基础配置接口
export interface formItemInter {
//此外段为formItem上的属性
type: formItemType
label: string
name: string
rules?: Array<object>
width?: string
//props配置为用到的组件上的属性
props?: {
disabled?: boolean
placeholder?: string
name?: string
'value-format'?: string
type?: string
size?: string
clearable?: boolean
'default-value'?: any
'default-time'?: any
}
render?: (renderCallbackParams: any) => VNode | VNode[] | string
}
import { ElInput, ElDatePicker } from 'element-plus'
export const formItemMap = new Map()
formItemMap.set('input', ElInput)
formItemMap.set('datePicker', ElDatePicker)
index.vue文件
<template>
<el-form :model="formState" ref="formRef">
<el-form-item v-for="item in formItems" :key="item.name" :label="item.label">
<Item :itemProps="item" :modelValue="formState[item.name]" @changeVal="changeVal" @changeItemCom="changeCom"/>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import Item from './formItem/Item.vue';
import { formItemInter } from './config';
const emits = defineEmits(['changeCom']);
//外部传入的需求项
const props = defineProps({
//表单参数项
formItems: {
type: Array<formItemInter>,
default: () => [],
},
//表单对应的值
formState: {
type: Object,
default: () => ({}),
},
});
//数据改变时的双向绑定
const changeVal = (obj:any) => {
console.log(props.formState,'数据双向绑定');
props.formState[obj.key.name] = obj.value;
// emits('change', obj);
};
//数据改变时的抛出其他需要的数据
const changeCom = (obj:any) => {
emits('changeCom', obj);
};
</script>
<style lang="scss" scoped></style>
3、组件使用例子如下
- .vue文件
<template>
<MyForm :formItems="editFormItem" :formState="formArr.data"></MyForm>
</template>
<script lang="ts" setup>
import { editFormItem } from './work.data';
import { reactive } from 'vue'
const formArr = reactive({
data: {}
})
</script>
<style lang="scss" scoped></style>
- XX.data.ts文件
import { formItemInter } from '@/components/form/config';
import { reactive } from 'vue';
export const editFormItem: Array<formItemInter> = reactive([
{
type: 'input',
label: '常驻人口',
name: 'iptval',
props: {
placeholder: '请输入',
},
},
{
type: 'datePicker',
label: '时间选择',
name: 'iptval1',
props: {
type: 'datetime',
placeholder: '请选择时间',
'value-format' : 'YYYY-MM-DD HH:mm:ss',
},
},
]);
最后,如有不足和改进之处,还望指出