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" }

  

posted @ 2021-04-15 15:34  winyh  阅读(230)  评论(0编辑  收藏  举报