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 { |
| |
| type: formItemType |
| label: string |
| name: string |
| rules?: Array<object> |
| width?: string |
| |
| 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; |
| |
| }; |
| |
| const changeCom = (obj:any) => { |
| emits('changeCom', obj); |
| }; |
| </script> |
| |
| <style lang="scss" scoped></style> |
| |
复制
3、组件使用例子如下
| <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> |
| |
复制
| 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', |
| }, |
| }, |
| ]); |
复制
最后,如有不足和改进之处,还望指出