Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

建议 Form 组件 提供类似 labelWidth API 或优化 labelCol 和 wrapperCol #450

Open
1 task done
EryouHao opened this issue Jan 28, 2019 · 4 comments
Open
1 task done

Comments

@EryouHao
Copy link

EryouHao commented Jan 28, 2019

  • I have searched the issues of this repository and believe that this is not a duplicate.

What problem does this feature solve?

之前使用 element 等 组件库的时候,发现 labelWidth 这个属性体验舒适,自己写组件库的时候也发现这个属性提供继承和 item 优先级更高的 API 蛮好的。
我目前能想到的是因为 ant design react 的没有实现,然后 vue 的为了保持 api 一致所以也没有提供😂

说一个技术实现上的小点,当然您估计更清楚,用 provide 和 inject 可以很方便地实现这种 API。

当使用 labelCol 和 wrapperCol 进行表单布局的时候,发现了两个不适:

  1. 表单过多时,可以说是两个及以上时,就发现出现重复代码,如果更多时,不适感更强,虽然可以通过抽象具体代码或通过 for 循环做一些代码瘦身。
  2. 使用这两个属性布局时,当页面宽度动态改变时,有时会发生 label 被表单空间遮盖问题,label没有自动换行(这个应该可以通过 css 解决,或通过组件库种的其他 API 解决,没有详细了解)

另外,一般情况下表单元素都是相同的 labelWidth 以保持布局对齐,所以 父组件(Form)提供控制 (Form.Item)的布局能力个人觉得蛮好的。

What does the proposed API look like?

建议提供 Form 直接管理表单布局的能力

@tangjinzhou
Copy link
Member

ref ant-design/ant-design#15006

@zzzz-Z
Copy link

zzzz-Z commented Apr 4, 2019

这是我自己的实现

import { Component, Prop } from 'vue-property-decorator'
import { Form } from 'ant-design-vue';
import { IFormProps } from '@/types/form';
import { VC } from '@/VC-vue';
import { FormUtils } from '@/types/form-ref';

const props = [
  'layout',
  'formItems',
  'labelCol',
  'col',
  'form',
  'wrapperCol',
  'itemStyle',
  'initialValues'
]


@Component({ props })
class VcForm extends VC<IFormProps> {

  @Prop() form!: FormUtils

  get renderItem() {
    const { labelCol, wrapperCol, initialValues, itemStyle, col, formItems } = this.$props
    const form = this.form

    return (formItems || []).map((props) => {
      // tslint:disable-next-line:prefer-const
      let { field, rules, initialValue, el } = props

      let element = <a-input type={props.type} placeholder={props.placeholder} />

      el && (element = typeof el === 'function' ? el(form) : el)

      typeof rules === 'function' && (rules = rules(form))

      if (field) {
        initialValues && Object.keys(initialValues).includes(field) && (initialValue = initialValues[field])
        element = form.getFieldDecorator(field, { rules, initialValue })(element)
      }

      const formItemProps = { props: { labelCol, wrapperCol, ...props } }
      const colProps = { props: col }
      const style = props.style || itemStyle

      return (
        <a-col {...colProps} style={style} >
          <a-form-item   {...formItemProps}  >
            {element}
          </a-form-item>
        </a-col>
      )
    })
  }

  render() {
    return (
      <a-row>
        <a-form layout={this.$props.layout} >
          {this.renderItem}
        </a-form>
      </a-row>
    )
  }
}


const FormInstance = Form.create({ props })(VcForm)
const IForm = ({ data }: FC<IFormProps>) => <FormInstance {...data} />

export default IForm

@zzzz-Z
Copy link

zzzz-Z commented Apr 4, 2019

    <IForm
      initialValues={props.initialValues || {}}
      labelCol={{ span: 6}}
      wrapperCol={{ span: 13 }}
      formItems={[{
        field: 'title',
        label: '标题',
        placeholder: '标题'
      }, {
        field: 'time',
        label: '起止时间',
        el: <a-date-picker />
      }, {
        field: 'doc',
        label: '目标描述',
        el: () => <a-textarea placeholder='Basic usage' rows={4} />
      }, {
        field: 'norm',
        label: '衡量标准',
        el: () => <a-textarea placeholder='请输入衡量标准' rows={4} />
      }, {
        field: 'user',
        placeholder: '请描述你服务的客户, name',
        label: (
          <span>
            客户<span style='color:rgba(0,0,0,.45)' > ( 选 填 )
            <a-tooltip title='目标服务对象'><a-icon style='margin-left:5px;' type='info-circle' /></a-tooltip>
            </span>
          </span>
        )
      }, {
        field: 'person',
        placeholder: '请描述你服务的客户, name',
        label: <span>邀评人<span style='color:rgba(0,0,0,.45)'>( 选 填 )</span> </span>
      }, {
        field: 'qz',
        label: <span>权重<span style='color:rgba(0,0,0,.45)'>( 选 填 )</span></span>,
        el: (<span><a-input placeholder='请填写' style='width:20%' /> %</span>)
      }, {
        field: 'mb',
        label: '目标公开',
        initialValue: '1',
        el: (
          <a-radio-group name='radioGroup'>
            <a-radio value='1'>公开</a-radio>
            <a-radio value='2'>部分公开</a-radio>
            <a-radio value='3'>不公开</a-radio>
          </a-radio-group>
        )
      }, {
        wrapperCol: { offset: 6 },
        el: (form) => (
          <div>
            <a-button
              onClick={() => submit(form.getFieldsValue())}
              v-html='提交'
              type='primary'
              style='margin-right:20px' />
            <a-button v-html='保存' />
          </div>
        )
      }]} />

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the Stale label Feb 25, 2021
@github-actions github-actions bot removed the Stale label Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants