vue + ts + element-ui 动态生成动态表单

目录

    • 1、一些说明
    • 2、主要render函数的写法
    • 3、数据结构
    • 4、表单控件的写法
    • 5、在父级中获得填写的数据
    • 6、demo

1、一些说明

本文基于 vue-cli 3.x 生成 ts vue项目上写的
2.x的朋友可能还需要改改,目前只是一些简单的表单,后期也许会有后续更新。

2、主要render函数的写法

这个为主要的 render 函数

import input from './Input';
import select from './Select';
import radio from './Radio';
import checkbox from './CheckBox'
import textarea from './Textarea'
import textdesc from './TextDesc'
import { Vue, Component, Prop } from 'vue-property-decorator';


const form_item :any = {
  input,
  select,
  radio,
  checkbox,
  textarea,
  textdesc
};

@Component
export default class extends Vue {
  @Prop() obj !:any
  @Prop() value !: any
  @Prop() sure !:boolean
  @Prop() ele !: string
  @Prop() rinx !:number

  
  render(h :any) :any {
    let form_prop = {
      props: {
        prop: this.obj.name,
        label: this.ele == 'textdesc' ? "" : `${this.rinx + 1}${this.obj.label}:`,
        rules: this.obj.required ? [{ required: true, message: '此项不能为空', trigger: 'blur' }] : []
      }
    }
    return h('el-form-item', 
    form_prop, 
    [h('pre', {}, this.obj.desc),form_item[this.ele](this, h)]);
    // 这里如果只渲染一个文件可以不用  []
    // 可直接写成 form_item[this.ele](this, h)
  }
} 

render 函数的一些解释

h('el-form-item', 
     {
      props: {
        prop: this.obj.name,
        label: this.ele == 'textdesc' ? "" : `${this.rinx + 1}${this.obj.label}:`,
        rules: this.obj.required ? [{ required: true, message: '此项不能为空', trigger: 'blur' }] : []
      }
    },
    [h('pre', {}, this.obj.desc),form_item[this.ele](this, h)]);

el-form-item是指 写作el-form-itemhtml节点

<el-form-item>el-form-item>

props 是指其需要绑定的props

<el-form-item  :prop='obj.name' :label='obj.label'>el-form-item>

最后一项则为其内容

<el-form-item  :prop='obj.name' :label='obj.label'>
	<pre>{{ obj.desc }}pre>
el-form-item>

3、数据结构

这里是我自己的定义,并不是规定的写法。

 let qestion :any = {
 			// type 为item的类型 如 input select等
	       ele: type,
	       obj: {
	         label: '问题',
	         // 为了确保每个item的名字不重复
	         name: type + this.list.length, 
	         desc:'',
	         // 是否为必填
	         required: type == 'textdesc' ? false : true
	       }
	     }

4、表单控件的写法

以 el-input 为例

export default (_self :any, h :any) => {
  return [
    h("el-input", {
      props: {
        value: _self.value, // 获取以前的value
      },
      'class': {
        inp: true // 是否带有此 class
      },
      on: {
        "input": function (val :any) {
          if (!_self.obj.name) {
            return false;
          }
          
		// 这个地方做一下判断,不然会提示 event 有可能为 null
          let current: any = event && event.currentTarget ? event.currentTarget : ''
          _self.$emit('handleChangeVal', current.value, _self.obj.name)
        }
      }
    })
  ];
};

以 el-select 为例

export default (_self: any, h: any) => {
  return [
    h("el-select", {
      props: {
        placeholder: _self.obj.placeholder || "这是一个下拉框",
        value: _self.value
      },
      on: {
        "change": function (val: any) {
          if (!_self.obj.name) {
            return false;
          }
          _self.$emit('handleChangeVal', val, _self.obj.name)
        }
      }
    },
      _self.obj.items.map((v:any) => {
        return h("el-option", {
          props: {
            label: v.label,
            value: v.label,
            disabled: v.diss,
          },
        })
      }))
  ];
};

强调:
el-radio和el-checkbox,值改变均为 input 而不是 change

5、在父级中获得填写的数据

// 函数名字为在表单控件中设置的 emit 的 名字
handleChangeVal(val :any,ele_name :any){
      this.$set(['object的名字'], ele_name, val);
    }

6、demo

有时间再更新

你可能感兴趣的:(vue)