在这个全民都在哭着喊着“降本增效”的时代,越来越多的扯淡的“卷略”在那些神神鬼鬼的公司给逐步卷了出来。同时为了解决所谓的客户的“痛点”,公司内部的各个部门在逐步“对齐颗粒度”的情况下,以科技“赋能”业务,以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.vue 和 consts.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端一问一答的方式,感觉有点繁琐,所以干脆我就自己去实现了。
最后再多说一句低代码,这个玩意儿咋说呢,跟上文所提到的现象类似,现在是个科技类公司,都想搞低代码。首先声明,我说的低代码不是指市面上的低代码平台,我想说的是那些通过拖拉拽生成页面的低代码,那玩意儿的效率真的很高吗?你用过吗?反正谁用谁知道。有这种一键生成代码模板的实现,他不香吗?

