Vue 超级表单
import Vue from "vue" import { Form, Button, Space, Icon, Row, Col } from "ant-design-vue" import { props } from "./props" const BaseFormPro = { name: "FormPro", extends: Form, props: { ...props }, data() { const { items, limit } = this.$props return { expand: limit >= items.length ? true : false, innerItems: limit < items.length ? items.slice(0, limit) : items } }, computed: { itemLayout() { const { layout } = this const { labelCol = { span: 6 }, wrapperCol = { span: 18 } } = this.$props return layout === "horizontal" ? { labelCol, wrapperCol } : {} } }, watch: { items: { handler(val) { this.innerItems = val }, immediate: true, deep: true } }, render() { const { items, initialValues, isRule, span, limit, btnText, btnHidden, ...formRest } = this.$props const { expand, innerItems, form, itemLayout } = this const onSubmit = () => { form.validateFieldsAndScroll((err, values) => { if (!err) { this.$emit("submit", values) } else { this.$emit("fail", err) } }) } const onReset = () => { form.resetFields() this.$emit("reset") } const onExpand = () => { this.expand = !expand this.innerItems = expand ? items.slice(0, limit) : items } const btnLayout = { ...itemLayout.wrapperCol } const components = Object.keys(Vue.options.components) const target = itemLayout.labelCol if (target && target.span) btnLayout.offset = target.span return ( <Form props={{ ...formRest, form }}> <Row gutter={16}> {innerItems.map((item) => { const { is, label, name, value, valuePropName, rules, itemSpan, labelCol, wrapperCol, style, attrs, classObj, on, ...rest } = item /* 避免程序中断, 否则可以直接 throw */ try { var Tag = `A${is}` if (!components.includes(Tag)) { Tag = `P${is}` if (!components.includes(Tag)) { throw new Error(`哈哈哈哈...小样儿,组件 ${Tag} 没注册吧?`) } } } catch (error) { console.error(error) } const decorator = { initialValue: value ? value : initialValues[name] } if (valuePropName) decorator.valuePropName = valuePropName if (isRule) decorator.rules = rules return ( <Col span={itemSpan ? itemSpan : span}> <Form.Item label={label} labelCol={labelCol ? labelCol : itemLayout.labelCol} wrapperCol={wrapperCol ? wrapperCol : itemLayout.wrapperCol} > <Tag v-decorator={[name, decorator]} props={rest} style={style} attrs={attrs} class={classObj} on={on} ></Tag> </Form.Item> </Col> ) })} {btnHidden ? null : ( <Col span={span}> <Form.Item wrapperCol={btnLayout}> <Space> <Button onClick={onSubmit} type="primary"> {btnText} </Button> <Button onClick={onReset}>重置</Button> {limit <= innerItems.length ? ( <a onClick={onExpand}> {expand ? "收起" : "展开"} <Icon type={expand ? "up" : "down"} /> </a> ) : null} </Space> </Form.Item> </Col> )} </Row> </Form> ) } } export default { ...Form.create({})(BaseFormPro), name: "PFormPro" }