zoukankan      html  css  js  c++  java
  • element-ui 通用表单封装及VUE JSX应用

    一、存在及需要解决的问题

    一般在做后台OA的时候会发现表单重复代码比较多,且逻辑基本一样,每次新加一个表单都需要拷贝基本一致的代码结构,然后只是简单地修改对应的字段进行开发

    二、预期结果

    提取重复的表单逻辑形成通用的组件,通过约定的JSON数据结构配置生成表单

    1、使用方法

    <common-form :form-option="formOption" :is-reset-form-flag="isResetFormFlag"></common-form>
    复制代码

    接收的props:

    isResetFormFlag:是否更新表单内容标志,用于触发更新表单的formModel

    formOption:表单配置,下有详细配置说明

    isDisabled:表单是否可编辑

    2、单一表单组配置

    {
      name: 'channel-form',
      data: {},
      items: [
        {
          label: '类型',
          name: 'biz_type',
          type: 'select',
          dataList: [{
            index: 1,
            text: '业务部'
          }]
        }
      ],
      rules: {
        name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }]
      },
      btnList: [{
        text: '保存',
        type: 'primary',
        onClick: this.commitForm
      }]
    }
    复制代码

    3、多表单组配置

    formOption: {
     name: 'channel-form',
     data: {},
     groups: [{
       title: '',// 组标题
       tips: ''// 组提示
       items: [] // 组表单项,和单一组配置一致
     }]
    }
    复制代码

    三、实现逻辑

    根据配置输出不同的form-item,需要特殊处理的表单项通过jsx由使用的地方自定义实现

    什么是JSX:cn.vuejs.org/v2/guide/re…

    文档:egoist.moe/2017/09/21/…

    使用JSX原因:表单包含了大部分的选项,但是也有很多不确定的情况需要依赖外部自己实现,相对于template的方式jsx使用起来更加灵活

    四、配置文档

    节点 描述 类型 是否必须 备注
    name 表单名 String 默认名 oa-form
    data 表单数据 Object 用于编辑场景异步请求的表单填充数据
    groups 表单组 Array groups 和 items 不应该同时存在,groups 中包含了items,如果groups为空取外部的items渲染,groups不为空仅渲染groups组内容
    items 表单项 Array 支持的type类型:输入框:input、textarea;多选框:checkbox;单选框:radio;下拉菜单:select
    rules 表单校验规则 Object 节点名需要与items配置的name一一对应
    btnList 按钮列表 Array 会在回调函数包含表单的数据及表单引用

    六、VUE JSX 遇到的一些问题

    v-model支持: babel-plugin-jsx-v-model

    sync 修饰符写法

    visible={ this.dialogImgVisible } {...{on: {'update:visible': (val) => { this.dialogImgVisible = val }}}}
    复制代码

    七、部分实现代码

    1、生成列表

    generateList (itemObj) {
      let itemEle = []
      for (let index = 0; index < itemObj.dataList.length; index++) {
        const item = itemObj.dataList[index]
        switch (itemObj.type) {
          // 下拉菜单
          case 'select':
            itemEle.push(<el-option key={ item.index } label={ item.text } value={ item.index }></el-option>)
            break
          // 多选框
          case 'checkbox':
            itemEle.push(<el-checkbox label={ item.index }>{ item.text }</el-checkbox>)
            break
          // 单选框
          case 'radio':
            itemEle.push(<el-radio label={ item.index }>{ item.text }</el-radio>)
            break
        }
      }
      return itemEle
    }
    复制代码

    2、生成下拉菜单

    generateSelect (item) {
      return <el-select v-model={ this.formModel[item.name] } style={ item.style || this.defaultStyle }>{ this.generateList(item) }</el-select>
    }
    复制代码

    备注:其他项实现类似

    3、render函数

    render (h) {
        let ele = []
        // 表单内容
        if (this.isGroup) {
          ele = this.generateGroup()
        } else {
          ele = this.generateFormItems(this.formOption.items)
        }
        // 按钮列表
        let btnListEle = []
        this.formOption.btnList.forEach((btn) => {
          btnListEle.push(<el-button type={ btn.type } on-click={ () => { btn.onClick(this.$refs[this.formName], this.formModel) } }>{ btn.text }</el-button>)
        })
        return (
          <div class="oa-form-container">
            <el-form ref={ this.formName } model={ this.formModel } rules={ this.formOption.rules } inline={ this.inline } disabled={ this.isDisabled } label-width={ this.formOption.labelWidth || '150px'}>
              { ele }
              <el-form-item label-width={ this.isGroup ? '0' : '150px'}>{ btnListEle }</el-form-item>
            </el-form>
          </div>
        )
      }
    复制代码

    八、最后贴一个表格的封装

    <script>
    export default {
      props: {
        // 表格列
        columns: {
          type: Array,
          default: _ => { return [] }
        },
        // 表格数据
        tableData: {
          type: Array,
          default: _ => { return [] }
        },
        // loading 标志
        loading: {
          type: Boolean,
          default: false
        }
      },
      methods: {
        sortChange (obj) {
          this.$emit('sortChange', obj)
        }
      },
      render () {
        return (
          <el-table border stripe v-loading={ this.loading } element-loading-text="拼命加载中" data={ this.tableData } on-sort-change={ obj => { this.sortChange(obj) } } style=" 100%">
            {
              this.columns.map(columnObj => {
                return <el-table-column prop={ columnObj.prop } label={ columnObj.label } sortable={ columnObj.sortable } width={ columnObj.width }
                  {...{
                    scopedSlots: {
                      default: scope => {
                        return columnObj.hasOwnProperty('render') ? columnObj.render(scope.index, scope.row) : scope.row[columnObj.prop]
                      }
                    }
                  }}
                >
                </el-table-column>
              })
            }
          </el-table>
        )
      }
    }
    </script>
    复制代码

    1、使用方法

    <common-table :columns="columns" :table-data="tableData" :loading="loading" @sort-change="sortChange"></common-table>
    复制代码

    2、columns 配置

    {
        label: '',
        prop: '',
         '100',
        sortable: true
        render: ()=>{}
    }
    复制代码

    自定义配置渲染,传入render函数,如果有render函数,优先使用render函数结果

    Github地址:github.com/mrtanweijie…

  • 相关阅读:
    安卓虚拟机启动后报错: 类似 SDK Manager] Error: Error parsing .....devices.xml 解决方案
    error when loading the sdk 发现了元素 d:skin 开头无效内容 转自http://blog.csdn.net/yueqinglkong/article/details/46340571
    mysql 5.5及以前版本的编码问题“Incorrect string value: 'xE6x9BxB9xE5x86xAC...' for column 'realname' at row 1”
    HDU 1024 Max Sum Plus Plus(基础dp)
    POJ 3026 --Borg Maze(bfs,最小生成树,英语题意题,卡格式)
    算法分类合集(转)
    ACM训练计划建议(转)
    The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
    The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
    iOS消息推送机制的实现
  • 原文地址:https://www.cnblogs.com/twodog/p/12134939.html
Copyright © 2011-2022 走看看