手搓低代码表单(三)属性配置区

手搓低代码表单(二)属性配置区

在前一节中,我们实现了表单渲染,但实际开发过程中,表单的属性需要支持修改,比如表单的label,是否禁用disabled,是否展示show-word-limit等等, 对于属性的修改,只需要修改表单项对应schema中定义属性的value值即可,然后实时响应到画布区。

属性配置区我们分为两块:

  • 组件属性编辑区

组件属性编辑区用来配置组件的属性,比如label,labelWidth,showLabel,changeTag,tag,tagIcon,defaultValue,required,layout,span,document,regList等等。

  • 表单属性编辑区

表单属性编辑区用来配置表单的属性,比如size,labelPosition,labelWidth,labelSuffix,hideRequiredAsterisk,disabled,gutter,formBtns,unFocusedComponentBorder等等。

最终要实现的效果图如下:

组件属性编辑区

props数据的绑定

编辑区的组件属性编辑区,我们还是以el-input为例,以下是对el-input的定义:

js 复制代码
  const elInput = {
    __config__: {
       label: '单行文本',
          labelWidth: null,
          showLabel: true,
          changeTag: true,
          tag: 'el-input',
          tagIcon: 'input',
          defaultValue: undefined,
          required: true,
          layout: 'colFormItem',
          span: 24,
          document: 'https://element.eleme.cn/#/zh-CN/component/input',
          // 正则校验规则
          regList: [{
          pattern: '/^1(3|4|5|7|8|9)\d{9}$/',
          message: '手机号格式错误'
       }]
    },
    // 组件的插槽属性
    __slot__: {
       prepend: '',
          append: ''
    },
    __vModel__: 'mobile',
       placeholder: '请输入手机号',
       style: { width: '100%' },
    clearable: true,
       'prefix-icon': 'el-icon-mobile',
       'suffix-icon': '',
       maxlength: 11,
       'show-word-limit': true,
       readonly: false,
       disabled: false
}

这里以label属性为例,在右侧编辑区,我们通过v-model绑定了activeDataactiveData为当前选中组件)的label属性,这样我们就可以实时的修改数据。其他的props属性与之类似。

js 复制代码
<el-form-item v-if="activeData.__config__.label!==undefined" label="标题">
    <el-input v-model="activeData.__config__.label" placeholder="请输入标题" />
</el-form-item>

vModel绑定

vModel绑定如下,也是直接绑定到activeData中定义的__vModel__属性。

js 复制代码
<el-form-item v-if="activeData.__vModel__ !== undefined" label="字段名">
    <el-input v-model="activeData.__vModel__" placeholder="请输入字段名" />
</el-form-item>

举个例子:当我们创建一个用户名的表单项,我们可以给它绑定一个字段名,比如username,当我们在画布区中的用户名表单项中输入xunwukong时,那么xunwukong其实是绑定到了defaultValue上。

插槽属性绑定

插槽的绑定与props属性类似,在el-input中,我们定义了__slot__属性,在绑定的时候,也是通过v-model绑定到activeData中定义的__slot__属性。

js 复制代码
 <el-form-item v-if="activeData.__slot__&&activeData.__slot__.prepend!==undefined" label="前缀">
    <el-input v-model="activeData.__slot__.prepend" placeholder="请输入前缀" />
</el-form-item>
<el-form-item v-if="activeData.__slot__&&activeData.__slot__.append!==undefined" label="后缀">
    <el-input v-model="activeData.__slot__.append" placeholder="请输入后缀" />
</el-form-item>

番外

这里我们仅仅对el-input进行了配置,实际上对于不同的组件,配置也是不同的,我们可以根据需求进行扩展,比如el-select组件,有和el-input公用的属性,也有不同的属性,el-select中有options属性,options在配置的时候,我们就需要支持添加选项,支持修改选项的先后顺序,支持删除选项,这些配置都是和el-select相关的,这里我们也简单举个例子, 如下是el-select的定义:

js 复制代码
const selectComponents = [
    {
       __config__: {
          label: '下拉选择',
          showLabel: true,
          labelWidth: null,
          tag: 'el-select',
          tagIcon: 'select',
          layout: 'colFormItem',
          span: 24,
          required: true,
          regList: [],
          changeTag: true,
          document: 'https://element.eleme.cn/#/zh-CN/component/select'
       },
       __slot__: {
          options: [{
             label: '选项一',
             value: 1
          }, {
             label: '选项二',
             value: 2
          }]
       },
       placeholder: '请选择',
       style: { width: '100%' },
       clearable: true,
       disabled: false,
       filterable: false,
       multiple: false
    }
]

options中配置了下拉选项,在渲染的时候通过遍历options属性,渲染出下拉选项:

js 复制代码
options(h, conf) {
       const list  = []

       conf.__slot__.options.forEach(item => {
          list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
       })

       return list
    }

如上代码所示,options属性是一个函数,函数接收两个参数,一个是h,一个是confh是createElement的别名,conf是当前选中的组件的配置信息。 在编辑区域中,我们通过v-model绑定到activeData中定义的__slot__属性上:

vue 复制代码
 <template v-if="['el-select'].includes(activeData.__config__.tag)">
  <el-divider>选项</el-divider>
  <draggable
      :list="activeData.__slot__.options"
      :animation="300"
      group="selectItem"
      handle=".option-drag"
  >
    <div v-for="(item, index) in activeData.__slot__.options" :key="index" class="select-item">
      <div class="select-line-icon option-drag">
        <i class="el-icon-s-operation" />
      </div>
      <el-input v-model="item.label" placeholder="选项名" size="small" />
      <el-input :value="item.value" size="small" @input="setOptionValue(item, $event)" placeholder="选项值" />
      <div class="close-btn select-line-icon" @click="activeData.__slot__.options.splice(index, 1)">
        <i class="el-icon-remove-outline" />
      </div>
    </div>
  </draggable>
  <div style="margin-left: 20px;">
    <el-button
        style="padding-bottom: 0"
        icon="el-icon-circle-plus-outline"
        type="text"
        @click="addSelectItem">
      添加选项
    </el-button>
  </div>
  <el-divider />
</template>

在上述代码中,遍历options属性,渲染出下拉选项。同时支持添加选项,删除选项等功能,同时通过draggable组件支持拖拽排序。

表单校验配置

每个表单项可能有对应的校验规则,比如requiredpattern等等,这些属性我们可以通过v-model绑定到activeData中定义的regList属性上。

vue 复制代码
<template v-if="Array.isArray(activeData.__config__.regList)">
  <el-divider>正则校验</el-divider>
  <div
      v-for="(item, index) in activeData.__config__.regList"
      :key="index"
      class="reg-item"
  >
              <span class="close-btn" @click="activeData.__config__.regList.splice(index, 1)">
                <i class="el-icon-close" />
              </span>
    <el-form-item label="表达式">
      <el-input v-model="item.pattern" placeholder="请输入正则" />
    </el-form-item>
    <el-form-item label="错误提示" style="margin-bottom:0">
      <el-input v-model="item.message" placeholder="请输入错误提示" />
    </el-form-item>
  </div>
  <div style="margin-left: 20px">
    <el-button icon="el-icon-circle-plus-outline" type="text" @click="addReg">
      添加规则
    </el-button>
  </div>
</template>

如上所示,regList为一个数组,数组中的每个元素都是一个对象,对象中包含patternmessage两个属性,pattern为正则表达式,message为错误提示。同时我们可以添加新的规则。

表单属性编辑区

表单的属性作用于el-form组件,实现代码也比较简单:

vue 复制代码
<el-form-item label="表单名">
  <el-input v-model="formConf.formRef" placeholder="请输入表单名(ref)" />
</el-form-item>
<el-form-item label="表单模型">
  <el-input v-model="formConf.formModel" placeholder="请输入数据模型" />
</el-form-item>
<el-form-item label="校验模型">
  <el-input v-model="formConf.formRules" placeholder="请输入校验模型" />
</el-form-item>
<el-form-item label="表单尺寸">
  <el-radio-group v-model="formConf.size">
    <el-radio-button label="medium">
      中等
    </el-radio-button>
    <el-radio-button label="small">
      较小
    </el-radio-button>
    <el-radio-button label="mini">
      迷你
    </el-radio-button>
  </el-radio-group>
</el-form-item>

上述代码中我们通过v-model绑定了formConf中的属性,formRefel-form组件的ref属性,formModelel-form组件的model属性,formRulesel-form组件的rules属性,sizeel-form组件的size属性,其他的属性也是类似配置。

表单项的属性配置和表单的配置是不同的,表单项的配置是针对每个组件的,表单的配置是针对整个表单的,最终都是绑定到schema上来实现响应式的。

总结

今天我们把组件的属性编辑区实现完成,到目前为止,我们完成了物料区的开发,画布区的开发,属性编辑区的开发。还有一些功能点没有讲到,比如:画布区的表单项的拖拽,画布区的表单项的删除,画布区的表单项的复制,这些功能点比较简单,都是对画布区数据的增删改,就不细讲了。 我们在后续的文章中,会继续讲到出码的功能。

如果你喜欢我的内容,请点赞评论告诉我,我会努力做得更好!

系列链接:

1. 手搓低代码表单(一)整体设计以及物料区开发

2. 手搓低代码表单(二)画布区开发

相关推荐
Jiaberrr8 分钟前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho1 小时前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常2 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ2 小时前
html+css+js实现step进度条效果
javascript·css·html
小白学习日记2 小时前
【复习】HTML常用标签<table>
前端·html
程序员大金3 小时前
基于SpringBoot+Vue+MySQL的装修公司管理系统
vue.js·spring boot·mysql
john_hjy3 小时前
11. 异步编程
运维·服务器·javascript
风清扬_jd3 小时前
Chromium 中JavaScript Fetch API接口c++代码实现(二)
javascript·c++·chrome
丁总学Java3 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js