作者:hanjing0118 | 来源:互联网 | 2023-09-11 17:59
目录
- form文件夹
- FormItem.tsx
- 在页面中引用
- 总结
在系统中,表单作为用户与后端交互的重要传递组件使用频率极高,故对其进行封装是必然的,也是一个编写规范代码的前端程序员必须做的一件事。
在Vue3中封装组件时,能感受到与Vue2有着很大的不同,故作此记录。
form文件夹
![在这里插入图片描述](https://img1.php1.cn/3cd4a/24e5b/807/6531778d2dff810f.png)
FormItem.tsx
文件是Typescript中的新特性之一,详细可查阅TS中文文档index.vue
是主体文件type.ts
表单的规约
FormItem.tsx
import filter from "@/utils/filters"
import {
ElCheckbox,
ElCheckboxGroup,
ElDatePicker,
ElInput,
ElInputNumber,
ElOption,
ElRadio,
ElRadioGroup,
ElSelect,
ElTimePicker
} from "element-plus"
import { defineComponent } from "vue"
// 普通显示
const Span = (form: Record, data: Record) => (
{data.valueProp ? form[data.valueProp] : (data.filter ? filter(form[data.prop], data.filter) : form[data.prop] || "无")}
)
// 输入框
const Input = (form: Record, data: Record) => (
)
// 数字输入框
const InputNumber = (form: Record, data: Record) => (
)
const setLabelValue = (_item: any, { optionsKey }: any = {}) => {
return {
label: optionsKey ? _item[optionsKey.label] : _item.label,
value: optionsKey ? _item[optionsKey.value] : _item.value,
}
}
// 选择框
const Select = (form: Record, data: Record) => (
{data.options.map((item: any) => {
return
})}
)
// 单选/区间日期
const Date = (form: Record, data: Record) => (
)
// 单选/区间时间
const Time = (form: Record, data: Record) => (
)
// 单选
const Radio = (form: Record, data: Record) => (
{data.radios.map(
(item: { label: string | number | boolean; value: any }) => {
return (
{setLabelValue(item, data.prop).value}
)
},
)}
)
// 多选
const Checkbox = (form: Record, data: Record) => (
{data.checkboxs.map(
(item: { label: string | number | boolean; value: any }) => {
return (
{setLabelValue(item, data.prop).value}
)
},
)}
)
const setFormItem = (
form: Record | undefined,
data: Record,
editable: Boolean,
) => {
if (!form) return null
if (!editable) return Span(form, data)
switch (data.type) {
case "input":
return Input(form, data)
case "textarea":
return Input(form, data)
case "password":
return Input(form, data)
case "inputNumber":
return InputNumber(form, data)
case "select":
return Select(form, data)
case "date":
case "daterange":
return Date(form, data)
case "time":
return Time(form, data)
case "radio":
return Radio(form, data)
case "checkbox":
return Checkbox(form, data)
default:
return null
}
}
export default () =>
defineComponent({
props: {
data: Object,
formData: Object,
editable: Boolean,
},
setup(props) {
return () =>
props.data
? setFormItem(props.formData, props.data, props.editable)
: null
},
})
index.vue
type.ts
type itemType =
| "input"
| "select"
| "switch"
| "radio"
| "date"
| "time"
| "checkbox"
| "daterange"
interface FormProps {
inline?: Boolean
labelWidth?: string | number
labelPosition?: "left" | "top" | "right"
btn?: object[]
}
interface FormItems {
type: itemType
label?: string
prop: string
valueProp?: string
width?: string | number
span?: number
filter?: string
}
export class commonForm {
public data: any
private rules?: object
public elRowGutter?: number
public editable?: boolean
public formProps?: FormProps
public formItems: FormItems[]
public dataArray?:object[]
constructor({
data = {},
rules = {},
editable = true,
formProps = {},
formItems = [],
elRowGutter = 0,
}: any) {
this.data = data
this.rules = rules
this.elRowGutter = elRowGutter
this.editable = editable
this.formItems = formItems
this.formProps = formProps
}
}
在页面中引用
![在这里插入图片描述](https://img1.php1.cn/3cd4a/24e5b/807/5dbe59fdd9d7ecae.png)
changCarrier.vue
是主题页面,用来显示表单userForm.ts
是对表单进行渲染的数据项
index.vue
useForm
import { commonForm } from "@/components/common/form/type"
import { reactive } from "vue"
export default () => {
const rules = {
name: [
{ required: true, message: "人员名称", trigger: "blur" }
]
}
const form = reactive(
new commonForm({
data: [],
editable: true,
rules: rules,
formItems: [
{
label: "人员名称",
type: "select",
prop: "name",
},
{
label: "日期范围",
type: "daterange",
prop: "queueDate",
format:"YYYY-MM-DD",
valueFormat:"YYYY-MM-DD",
startPlaceholder:"开始时间",
endPlaceholder:"结束时间",
span: 6,
},
{
label: "时间段范围",
type: "time",
prop: "timeSlot",
format:"HH:mm",
valueFormat:"HH:mm",
start:"开始时间",
end:"结束时间",
isRange:true,
span: 6,
},
{
label: "允许排队数量",
type: "input",
prop: "queueNum",
span: 6,
},
{
label: "生效类型",
type: "select",
prop: "isDelay",
options: [
{
label: "当日生效",
value: 0,
},
{
label: "次日生效",
value: 1,
}
],
span: 6,
},
{
label: "生效时间",
type: "date",
prop: "effectiveTime",
format:"YYYY-MM-DD",
valueFormat:"YYYY-MM-DD",
span: 6,
},
],
}),
)
return form
}
总结
一百个人有一百个编写代码的习惯,其上实现是基于模块化的思想,可能看起来有点累,但是我相信能帮助到你。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程笔记。