JakHuang/form-generator

.vue代码生成器 · 开发教程

JakHuang opened this issue · 7 comments

《表单设计器 · 开发教程》el-button已经可以可视化配置属性了。如果你仅仅想使用json格式的表单配置,可以跳过本文,直接阅读《表单解析器 · 开发教程》
本文将继续完成vue代码生成器部分的教程。

点击【导出vue文件】按钮的时候,需要选择一个【生成类型】。说明目前支持生成,文件和弹框两种类型的代码。其实文件类型的代码用el-dialog包裹下就是弹框类型的代码了。
而生成代码的本质就是简单的字符串拼接。分别拼接出html、js、css三种类型的代码,最后组装成vue代码。

代码生成器中大量使用了:es6 模板字符串

一、生成html代码
在文件src\components\generator\html.js中添加el-button的html代码生成规则:
1.1 在tags对象中添加el-button属性,生成html

...
'el-button': el => {
  const {
    tag, disabled
  } = attrBuilder(el)
  const type = el.type ? `type="${el.type}"` : ''
  const icon = el.icon ? `icon="${el.icon}"` : ''
  const round = el.round ? 'round' : ''
  const size = el.size ? `size="${el.size}"` : ''
  const plain = el.plain ? 'plain' : ''
  const circle = el.circle ? 'circle' : ''
  let child = buildElButtonChild(el)

  if (child) child = `\n${child}\n` // 换行
  return `<${tag} ${type} ${icon} ${round} ${size} ${plain} ${disabled} ${circle}>${child}</${tag}>`
},
...

attrBuilder会生成常用的属性,这里与el-button匹配的是tag, disabled;其余属性都是和el-button组件属性对应的,目标是生成字符串:

`<el-button type="success" icon="el-icon-warning" size="medium"> 主要按钮 </el-button>`

1.2 由于按钮内的文字是配置在__slot__中的

__slot__: {
    default: '主要按钮'
 }

所以相应的应该去读取__slot__.default。为了保持和其他组件的统一,定义了函数buildElButtonChild读取__slot__.default。
在文件src\components\generator\html.js中添加buildElButtonChild函数:

// el-buttin 子级
function buildElButtonChild(scheme) {
  const children = []
  const slot = scheme.__slot__ || {}
  if (slot.default) {
    children.push(slot.default)
  }
  return children.join('\n')
}

写好了tags['el-button']和buildElButtonChild函数后,当再次点击运行按钮预览时,发现el-button组件已经可以预览了。

html.js中的代码都是字符串拼接处理并不高深,如需进一步的处理可以从入口函数

makeUpHtml

顺着结构阅读源码。

二、生成js脚本代码
在文件src\components\generator\js.js中,依然是通过字符串拼接的方式,生成脚本代码。

由于el-button无需js脚本,所以本文用el-input组件做讲解:

假设我们有如下的json配置:

{
  __config__: {
    tag: 'el-input',
    required: true,
    regList: [{
      pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
      message: '手机号格式错误'
    }]
  },
  __vModel__: 'mobile',
  placeholder: '请输入手机号',
}

目标是生成element UI表单校验js代码:

mobile: [{
  required: true,
  message: '请输入手机号',
  trigger: 'blur'
}, {
  pattern: /^1(3|4|5|7|8|9)\d{9}$/,
  message: '手机号格式错误',
  trigger: 'blur'
}]

json配置中有两个校验规则:required和regList,我们要做的代码生成,无非就是将json配置中的key和value,转化成js代码字符串。源码中的转化实现如下:

// 构建校验规则
function buildRules(scheme, ruleList) {
  const config = scheme.__config__
  if (scheme.__vModel__ === undefined) return
  const rules = []
  if (ruleTrigger[config.tag]) {
    if (config.required) {
      const type = isArray(config.defaultValue) ? 'type: \'array\',' : ''
      let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder
      if (message === undefined) message = `${config.label}不能为空`
      rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`)
    }
    if (config.regList && isArray(config.regList)) {
      config.regList.forEach(item => {
        if (item.pattern) {
          rules.push(
            `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }`
          )
        }
      })
    }
    ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`)
  }
}

上边的函数就是一个json配置key和value的搬运工,很朴实的一段代码,所以js.js中其他生成脚本的代码也不神秘,如有需要放开去看源码就行了,入口函数:

makeUpJs

三、生成css
css部分请直接看源码。文件:src\components\generator\css.js
重点看:

const styles = {
  'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
  'el-upload': '.el-upload__tip{line-height: 1.2;}'
}

此文件只做了一件简单事情:遍历待生成代码的json表单配置。如果配置中使用了el-rate或el-upload,将他们的css样式生成出去。这就是全部。入口函数:

makeUpCss

如果你要改写某个组件的默认样式,比如el-button,将你需要的css加进styles对象中即可。

本文相关代码,参阅vue代码生成器 · 开发教程代码

系列教程:
《表单设计器 · 开发教程》
《表单解析器 · 开发教程》
《vue代码生成器 · 开发教程》
《vue代码预览器 · 开发教程》

112312

什么时候搞一个执行自定义脚本的功能?

大佬你好,请问能反向生成么,改了代码然后转成相应的json

求大佬支持下 ant design vue的Vue文件导出

在html.js中添加‘\n’换行符为什么不起作用