手动实现简单的vue代码模板生成器

逻辑星芒
• 阅读 177

在这个全民都在哭着喊着“降本增效”的时代,越来越多的扯淡的“卷略”在那些神神鬼鬼的公司给逐步卷了出来。同时为了解决所谓的客户的“痛点”,公司内部的各个部门在逐步“对齐颗粒度”的情况下,以科技“赋能”业务,以AI为“抓手”,以OKR“倒逼”技术“沉淀”,加紧做好完美“闭环”,坚决“打通”与客户的“最后一公里”(好吧,我承认这些黑话确实很恶心)。

闲话休叙,但总而言之,言而总之,以上都是屁话。为了水篇幅,但凡我有一点办法,也不会一点办法都没有。

大家都知道,在公司上班,大多数时候你在你的项目中是很难下来的,是在不断的重复一些动作(包括ctrl+c、ctrl+v)而已,这些工作很难提升你的技术,也几乎没有时间让你去学习充电(降本增效就要卷嘛)。

但现在,既然是个公司都在提“降本增效”,那我们也不能闲着呀,你不增效,你可能就被降本了。这就来到了我们这篇文章的初衷了:增效。

我们这篇文章所介绍的,就是一个简单的内部管理系统的代码生成器。因为内部管理系统页面有着很高的相似度,所以一键生成这些高度相似的页面就能达成所谓的“增效”。

来吧,翠花,上代码:

generate.js

const fs = require('fs');
const path = require('path');
 
/**
 * @description 生成Vue组件的函数
 * @param { String } componentName 组件名称,例:dataScreen.vue
 * @param { String } dir 组件保存位置的文件夹名
 * @param { Boolean } hasForm 是否展示查询项,默认为true
 * @param { Boolean } hasButtons 是否展示按钮区域,默认为false
 */

function generateVueComponent({ componentName, dir, hasForm = true, hasButtons = false }) {
  // 表格的插槽
  let slot = ''
  // 引入组件所需的配置,默认引入表单组件和表格组件的配置
  // 是否展示form的submit事件,默认展示form的submit事件
  let hasSubmit = `submit(){
      this.$refs.table.reload()
    },
    list(page){
      return Promise.resolve({ data: [], total: 0 })
    }`
  // 是否在data中定义表单的配置,默认只有表格的配置
  let hasDataForm = `table: {
        headers: list,
        loadData: this.list
      }`
  // 只有查询项
  if(hasForm && !hasButtons){
    slot = '<Form slot="header" :config="form" ref="form" @submit="submit" />'
    hasDataForm = `form: {
        columns: form
      },
      table: {
        headers: list,
        loadData: this.list
      }`
  }
  // 有查询项和按钮区域
  if(hasForm && hasButtons){
    slot = `<template slot="header">
        <Form :config="form" ref="form" @submit="submit" />
        <div class="flex f-between pb8">
          <!--按钮区-->
          <el-button type="primary" size="mini">按钮</el-button>
        </div>
      </template>`
    hasDataForm = `form: {
        columns: form
      },
      table: {
        headers: list,
        loadData: this.list
      }`
  }
  // 只有按钮区域
  if(!hasForm && hasButtons){
    slot = `<div slot="header" class="flex f-between pb8">
        <!--按钮区-->
        <el-button type="primary" size="mini">按钮</el-button>
      </div>`
    hasSubmit = `list(page){
      return Promise.resolve({ data: [], total: 0 })
    }`
  }
  // 既没有查询项也没有按钮区域
  if(!hasForm && !hasButtons){
    hasSubmit = `list(page){
      return Promise.resolve({ data: [], total: 0 })
    }`
  }

  const template = `<template>
  <Container>
    ${slot ? `<Table type="Virtual" :config="table" ref="table">
      ${slot}
    </Table>` : '<Table type="Virtual" :config="table" ref="table" />'}
  </Container>
</template>

<script>
import { ${componentName} } from './consts'
${hasForm ? `const { form, list } = ${componentName}` : `const { list } = ${componentName}`}

export default {
  name: '${componentName}',
  data(){
    return {
      ${hasDataForm}
    }
  },
  methods: {
    ${hasSubmit}
  }
}
</script>
`

  // 生成配置项
  const consts = `const ${componentName} = {
    form: [
      { prop: 'productCode', label: '产品代码' },
      { prop: 'fullName', label: '产品名称' },
    ],
    list: [
      { prop: 'productCode', label: '产品代码', attrs: { minWidth: '100px' } },
      { prop: 'fullName', label: '产品名称', attrs: { minWidth: '180px' } },
    ]
  }
  
  export {
    ${componentName}
  }`

  const resolve = fileName => path.join(__dirname, '..', dir, fileName)

  // 生成vue文件名
  componentName = `${componentName}.vue`
  const filePath = resolve(componentName)
  // 生成consts.js
  const constName = 'consts.js'
  const constFilePath = resolve(constName)
 
  // 写入文件
  fs.writeFileSync(filePath, template, 'utf-8')
  fs.writeFileSync(constFilePath, consts, 'utf-8')
  
  console.log(`Vue component generated: ${componentName}`)
}
 
// 使用示例
generateVueComponent({ componentName: 'dataScreen', dir: 'generatedCode', hasForm: true, hasButtons: true });

以上代码,不支持在浏览器端运行,需要在node端运行。在 generate.js 所在的文件夹的vscode集成终端中使用 node generate.js 运行即可,最后会在 generate.js 所在的文件夹下生成 dataScreen.vueconsts.js 两个模板文件。

dataScreen.vue

<template>
  <Container>
    <Table type="Virtual" :config="table" ref="table">
      <template slot="header">
        <Form :config="form" ref="form" @submit="submit" />
        <div class="flex f-between pb8">
          <!--按钮区-->
          <el-button type="primary" size="mini">按钮</el-button>
        </div>
      </template>
    </Table>
  </Container>
</template>

<script>
import { dataScreen } from './consts'
const { form, list } = dataScreen

export default {
  name: 'dataScreen',
  data(){
    return {
      form: {
        columns: form
      },
      table: {
        headers: list,
        loadData: this.list
      }
    }
  },
  methods: {
    submit(){
      this.$refs.table.reload()
    },
    list(page){
      return Promise.resolve({ data: [], total: 0 })
    }
  }
}
</script>

consts.js

const dataScreen = {
    form: [
      { prop: 'productCode', label: '产品代码' },
      { prop: 'fullName', label: '产品名称' },
    ],
    list: [
      { prop: 'productCode', label: '产品代码', attrs: { minWidth: '100px' } },
      { prop: 'fullName', label: '产品名称', attrs: { minWidth: '180px' } },
    ]
  }
  
  export {
    dataScreen
  }

至于生成的文件中所封装的table组件和form组件不是本代码的主要实现,故不会展示此类代码的封装。

到这里,代码生成器的实现已经介绍完毕。在实现本代码之前,网上有关于plop代码生成器的介绍及实现,我试着用这个插件实现了一下,也基本能实现代码模板的生成,但它那个采取的是在node端一问一答的方式,感觉有点繁琐,所以干脆我就自己去实现了。

最后再多说一句低代码,这个玩意儿咋说呢,跟上文所提到的现象类似,现在是个科技类公司,都想搞低代码。首先声明,我说的低代码不是指市面上的低代码平台,我想说的是那些通过拖拉拽生成页面的低代码,那玩意儿的效率真的很高吗?你用过吗?反正谁用谁知道。有这种一键生成代码模板的实现,他不香吗?

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Peter20 Peter20
4年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Stella981 Stella981
4年前
Python+Selenium自动化篇
本篇文字主要学习selenium定位页面元素的集中方法,以百度首页为例子。0.元素定位方法主要有:id定位:find\_element\_by\_id('')name定位:find\_element\_by\_name('')class定位:find\_element\_by\_class\_name(''
Wesley13 Wesley13
4年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这