Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
JakHuang opened this issue May 5, 2020 · 7 comments
Open

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

JakHuang opened this issue May 5, 2020 · 7 comments

Comments

@JakHuang
Copy link
Owner

JakHuang commented May 5, 2020

《表单设计器 · 开发教程》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代码预览器 · 开发教程》

@JakHuang JakHuang changed the title .vue代码生成器生 · 开发教程 .vue代码生成器 · 开发教程 May 5, 2020
@rourkesu2015
Copy link

112312

@lzp0301
Copy link

lzp0301 commented Mar 2, 2021

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

@HunterXing
Copy link

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

@rourkesu2015
Copy link

rourkesu2015 commented Apr 28, 2022 via email

@zhangming
Copy link

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

@Wanan813
Copy link

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

@rourkesu2015
Copy link

rourkesu2015 commented Jun 27, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants