vue jsx使用-简单的form表单合并

jsx 使用文档:https://cn.vuejs.org/v2/guide/render-function.html

例子:

<script >
import * as _ from 'lodash'
import { reduce } from '../../util/func.js'

export default {
  props: {
    showBtn: {
      default: true
    },
    fields: {
      type: Array,
      required: true
    },
    values: {
      default: null
    },
    column: {
      default: 0
    },
    inline: {
      default: false
    },
    labelWidth: {
      default: '100px'
    },
    btnText: {
      default: '保存'
    },
    btnIcon: {
      default: undefined
    },
    btnHandler: {
      default: null
    }
  },
  data() {
    return {
      myValues: this.fields.reduce((rs, item) => {
        rs[item.dataIndex] = this.values ? this.values[item.dataIndex] : ''
        return rs
      }, {})
    }
  },
  computed: {
    columnSpan() {
      let c = this.column || 1
      if (this.column == 0 && this.fields.length > 6) {
        c = 2
      }
      return parseInt(24 / c)
    },
    myGroups() {
      let groups = {}
      this.fields.forEach((item, index) => {
        const {
          dataIndex,
          component = 'el-input',
          header: label,
          itemCls = '',
          itemStyle = '',
          itemOn = {},
          itemOpts = {},
          fieldCls = '',
          fieldStyle = {},
          fieldOn = {},
          group='其他',
          fieldOpts = {}
        } = item
        itemOpts.label = itemOpts.label || label
        itemOpts.prop = itemOpts.prop || dataIndex

        // 会覆盖
        // itemOpts.class = 'asdfasdf'
        fieldOpts.placeholder = fieldOpts.placeholder || label
        fieldOn.input = reduce([this.onInput.bind(this, dataIndex), fieldOn.input])

        groups[group] = groups[group] || []

        groups[group].push({
          dataIndex: dataIndex,
          dataKey: dataIndex + '-' + index,
          component,
          opts: {
            item: {
              attrs: {
                ...itemOpts
              },
              class: itemCls,
              style: itemStyle,
              on: {
                ...itemOn
              }
            },
            field: {
              attrs: {
                ...fieldOpts
              },
              class: fieldCls,
              style: fieldStyle,
              on: {
                ...fieldOn
              }
            }
          }
        })
      })
      return {
        hasLegend: Object.keys(groups).length > 1,
        items: Object.keys(groups).map(k => {
          return {
            group: k,
            items: groups[k]
          }
        })
      }
    }
  },
  methods: {
    submit() {
      this.btnHandler && this.btnHandler(this.myValues)
    },
    onInput(dataIndex, nv) {
      this.myValues[dataIndex] = nv
    },
    loadData(data) {
      data = data || {}
      Object.keys(this.myValues).forEach(k => {
        this.myValues[k] = data[k] || null
      })
    },
    reset() {
      this.loadData()
    },
    renderItem(item) {
      const Comp = item.component || 'el-input'
      let its=_.cloneDeep(item.opts.item)
      return (
        <el-form-item key={item.dataKey} {...its}>
          <Comp value={this.myValues[item.dataIndex]} {...item.opts.field} />
        </el-form-item>
      )
    }
  },
  render(h, ctx) {
    let me = this
    let child = null
    let myGroups=this.myGroups;
    if (this.inline) {
      child = myGroups.items[0].items.map(item => {
        return this.renderItem(item)
      })
    } else {
      child = myGroups.items.map(groupItem => {
        return (
          <fieldset
            class={myGroups.hasLegend ? 'has-legend' : 'no-legend'}
            key={groupItem.group}>
            {myGroups.hasLegend && <legend>{groupItem.group}</legend>}
            {groupItem.items.map(item => {
              return (
                <el-col span={this.columnSpan} key={item.dataKey}>
                  {this.renderItem(item)}
                </el-col>
              )
            })}
          </fieldset>
        )
      })
    }
    return (
      <el-form
        class="easy-form"
        inline={this.inline}
        labelWidth={this.labelWidth}
        attrs={{ ...this.$attrs, model: this.myValues }}
        on={{ ...this.$listeners }}>
        <input type="text" style="display:none;" />
        <input
          type="password"
          autocomplete="new-password"
          style="display:none;"
        />
        {
          child
        }
        {(this.showBtn && (
          <el-form-item>
            <el-button
              icon={this.btnIcon}
              onClick={this.submit.bind(this)}
              type="primary">
              {this.btnText}
            </el-button>
          </el-form-item>
        )) ||
          null}
        {this.$slots.default}
      </el-form>
    )
  }
}
</script>
<style lang="scss">
.easy-form {
  fieldset {
    border-width: 0;

    &.has-legend {
      border-color: #1d0e0e;

      border-top-width: 1px;
      legend {
        // color: #efefef;
        font-size: 14px;
      }
    }
  }
}
</style>

使用

 

<template>
  <div id="test">
    <div>
      <h1>typeScript{{ $locale('test.name') }}</h1>
    </div>
    <div>
      <el-radio-group v-model="column">
        <el-radio :label="1">1</el-radio>
        <el-radio :label="2">2</el-radio>
        <el-radio :label="3">3</el-radio>
        <el-radio :label="4">4</el-radio>
      </el-radio-group>
    </div>
    <easy-form  class="hello" :column="column" :fields="fields" :rules="rules">
      <h4>asdf</h4>
    </easy-form>
  </div>
</template>
<script>
export default {
  components: {
  },
  data() {
    return {
      column: 1,
      fields: [
        {
          header: '用户名',
          dataIndex: 'userName',
          group: 'hello',
          itemOn:{
            click:()=>{
              console.log('click')
            }
          },
          fieldOn:{
            focus:()=>{
              console.log('click field')
            }
          },
          itemStyle:{
            background:'black'
          },
          fieldStyle:{
            color:'green'
          },
          fieldCls:'test',
        },
        {
          header: '密码',
          dataIndex: 'password'
        }, {
          header: '密码6',
          dataIndex: 'password6',
          component:'select-category'
        },
        {
          header: '用户名1',
          dataIndex: 'userName1',
          component: 'date-range'
        },
        {
          header: '密码1',
          dataIndex: 'password1',
          component: 'upload-file'
        },
        {
          header: '用户名2',
          dataIndex: 'userName2',
          component: 'upload-img'
        },
        {
          header: '密码2',
          dataIndex: 'password2'
        },
        {
          header: '用户名3',
          dataIndex: 'userName3',
          component: 'el-date-picker'
        },
        {
          header: '密码3',
          dataIndex: 'password3',
          component: 'enum-select',
          fieldOpts: {
            enum: 'sex',
            type: 'radio'
          }
        },
        {
          header: '用户名4',
          dataIndex: 'userName4',
          component: 'enum-select',
          fieldOpts: {
            enum: 'vtype'
          }
        },
        {
          header: '密码4',
          dataIndex: 'password4',
          component: 'enum-select',
          fieldOpts: {
            getData() {
              return new Promise(resolve => {
                setTimeout(() => {
                  resolve({
                    result: {
                      list: [
                        { id: '1', name: 't1' },
                        { id: '2', name: 't2' },
                        { id: '3', name: 't3' },
                        { id: '4', name: 't4' },
                        { id: '5', name: 't5' }
                      ]
                    }
                  })
                }, 1500)
              })
            }
          }
        }
      ],
      rules: {
        userName: [this.$rules.required(), this.$rules.minLength(2)],
        password: [this.$rules.required(), this.$rules.minLength(2)]
      },
      name: 'name'
    }
  },
  mounted() {
    console.log('test')
    console.log(document.getElementById('test'))
    console.log(document.getElementById('t1'))
    console.log(document.getElementById('t2'))
  }
}
</script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值