骚年,请不要手敲 template 了

写在前面

每天搬砖,也早已变成了cv工程师。频繁的复制粘贴,复制完成后再删除,枯燥且无聊。项目中咱们一般在编辑器中配置快捷键生成代码片断。好像这些也知足不了cv的欲望。在项目中配置业务相关的一些模板文件,而后动态生成文件,显得尤其重要。不受编辑器的限制,更好的自定义配置,显得更为强大。html

先看效果

其实,生成代码片断的方式有不少,好比在代码编辑器中配置快捷键,就能够生成代码片断。好比在 vscode 里面安装插件也能够。虽然编辑器能够实现,可是不可以更加自定义。vue

在大型项目中,好多页面都是比较类似的,代码层面基本相似,一般新建一个页面组件,须要复制以前的一个页面、复制api配置文件、复制store中的文件,而后改一下相关变量,每每还会有漏改的状况。node

如今咱们能够将这部分代码的公共部分进行抽离作成一个模板文件,经过询问的方式获取是否须要添加部分代码片断。经过判断,而后生成的相应文件。这样咱们就能够造成一个该项目特有的通用代码的生成方式,提升工做效率妥妥的。git

主要步骤:github

  1. 抽离项目中公共代码,造成模板文件
  2. 经过 '询问' 收集,定制化页面的一些配置
  3. 生成相应的文件

这里使用plop工具进行一些配置,下面一块儿看看吧!web

安装

通常选择安装到本地项目中,执行下面命令进行安装:vuex

// 全局安装
npm i -g plop

// 本地安装
npm i plop -D
复制代码

配置 scripts 命令:npm

// package.json
"scripts": {
// ...
"g": "plop --plopfile generators/index.js"
// ...
}
复制代码

运行 npm run g 便可执行相关配置。其中 generators/index.js 为执行命令的入口文件。
相关配置后面慢慢介绍。json

基本使用

相关配置可参考官方文档,我仅仅介绍下,我本身在项目中的配置, 你们能够参考一下。api

这里我在我本身的一个项目基础上添加,项目地址为点击查看

generators/index.js 我配置了四种命令:

  • component:生成公共组件
  • views:生成页面
  • vuex:生成 store 中 modules 文件
  • api: 生成api配置文件
// 引入各模块配置文件
const componentGenerrator = require('./component/index.js')
const viewGenerrator = require('./view/index.js')
const storeGenerrator = require('./store/index.js')
const apiGenerrator = require('./api/index.js')

module.exports = plop => {
// component 相关
plop.setGenerator('component', componentGenerrator)
// views 相关
plop.setGenerator('views', viewGenerrator)
// vuex 相关
plop.setGenerator('vuex', storeGenerrator)
// api 相关
plop.setGenerator('api', apiGenerrator)
}
复制代码

首先展现下目录结构:

├ generators    // 所在文件加
├─api // api 相关
├─component // component 相关
├─store // vue 相关
├─utils // 工具函数
├─view // view 相关
└─index.js // 入口文件
复制代码

vuex 模块

首先预览下效果:

vuex 的模块中,主要是生成一个 modules 文件。根据模板文件生成文件,并放在 store/modules 文件夹下。模板文件以下:

// ./store/modules.hbs 模板文件
const state = {

}

const mutations = {

}

const actions = {

}

export default {
namespaced: true,
state,
mutations,
actions
}
复制代码

该模板的生成仍是十分简单,咱们只须要经过 '询问' 获取生成文件的文件名, 这里使用 modules 接受用户在命令行中输入的文件夹名称。而后在 actions 中 配置生成文件的文件路径便可。相关配置不作具体介绍,能够查看相关注释。

属性 类型 含义
description String 对该命令进行简要描述
prompts array 对用户进行询问
actions Array/Function 操做行为, 若为 Function ,入参为询问后收集的参数,返回 actions 配置
// ./store/index.js 配置文件
module.exports = {
description: 'vuex modules', // 这里是对该plop的功能描述
// 问题询问
prompts: [
{
type: 'input', // 问题类型 此处为输入
name: 'modules', // actions 和 hbs 模板文件中可以使用该变量
message: '请输入模块名称', // 问题
default:'app' // 问题的默认答案
}
],
// 操做行为
actions: [
{
type: 'add', // 操做类型,这里是添加文件
path: '../src/store/modules/{{kebabCase modules}}.js', // 添加的文件的路径
templateFile: './store/modules.hbs' // 模板文件的路径
}
]
}
复制代码

其中 kebabCase 可格式化数据,将 modules 转化为小驼峰的格式。
经常使用的还有下面的关键词,能够格式化用户输入参数:

  • camelCase: changeFormatToThis 小驼峰
  • properCase/pascalCase: ChangeFormatToThis 大驼峰

更多关键词,请查看相关文档点击查看

api 配置文件

首先预览下效果:

在api模块的配置和上述操做相似,我直接贴一下相关配置, 只介绍一下不一样的部分。

先准备好相应的模板文件以下:

// ./api/api.hbs
import Request from '@/utils/request'

export const get{{properCase file}}List = data => Request.get('{{kebabCase dir}}/{{kebabCase file}}', data)
复制代码

在项目中, api 配置文件我放在 /src/api 目录下,文件夹名称是对应页面的模块名,文件名是具体页面的名称,因此须要经过询问的方式,获取 dir参数 api 目录下要生成的文件夹名称、file参数对应的文件名称。

// ./api/index.js
module.exports = {
description: 'api 配置文件',
// 询问
prompts: [
{
type: 'input',
name: 'dir',
message: '请输入文件夹名称'
},
{
type: 'input',
name: 'file',
message: '请输入文件名称'
}
],
// 操做行为
actions: [
{
type: 'add',
path: '../src/api/{{camelCase dir}}/{{camelCase file}}.js',
templateFile: './api/api.hbs'
}
]
}
复制代码

views 页面

首先预览下效果:

该配置比前面的稍微复杂一点,可是一步一步分析也很容易理解。

下面经过设置的询问,慢慢解释!!!

  1. 请输入 views 所在文件夹名称!
    在该询问中,添加了重名验证,在输入重复名称时,会提示而且能够从新输入文件夹名称。保存用户输入至 dir 变量中。

  2. 请输入 views 名称!
    和以前的的配置没有什么区别,主要获取新建的文件名称。保存至变量 name 中。

  3. 是否须要 编辑弹窗 组件!
    将用户选择结果保存在 hasDialog 中,这样就能够在 actions 中根据 hasDialog 进行动态判断生成 action

  4. 是否添加 api 配置文件?

将用户选择结果保存在 hasApi 中,而后在 actions 中进行判断。此处能够直接执行已经配置好的命令来生成。这里使用 node 中的 child_process.exec函数执行命令 npm run g api ${dir} ${name} 便可。

  1. 是否添加 vuex moudule 文件?

同理根据 hasVuex 的值,执行 npm run g vuex ${name}命令便可

child_process.exec相关文档

actions 属性能够为函数,参数为用户输入变量,需返回 actions 的配置数组。

在通过上述询问后,咱们也获得了 hasDialog , hasApi , hasVuex , name , dir 相关的变量。同时,也须要在 .hbs 模板文件中动态的显示部分代码片断。

模板文件过多,这里就不贴出了,仅贴出关键部分。

// ./view/components.hbs
import { pagination } from '@/mixins'
{{#if hasApi}}
import { get{{properCase name}}List } from '@/api/{{kebabCase dir}}/{{kebabCase name}}'
{{/if}}
{{#if hasDialog}}
import { {{properCase name}}Dialog } from './components'
{{/if}}

export default {
name: 'Role',
{{#if hasDialog}}
components: {
{{properCase name}}Dialog
},
{{/if}}
mixins: [pagination], // 封装分页相关函数
data () {
return {
{{#if hasApi}}
listApi: get{{properCase name}}List, // 列表请求地址
{{/if}}
searchForm: {}
}
},
mounted () {
{{#if hasApi}}
this.getListData()
{{/if}}
},
methods: {
handleCheck (row) {
{{#if hasDialog}}
this.$refs.{{properCase name}}Dialog.openDialog(row, 'check')
{{/if}}
}
}
}
复制代码

下面为主要配置文件:

// ./view/index.js
const exec = require('child_process').exec
const componentExist = require('../utils/index')

module.exports = {
description: 'views 页面',
prompts: [
{
type: 'input',
name: 'dir',
default: 'container',
message: '请输入 views 所在文件夹名称!',
validate: value => {
if ((/.+/).test(value)) {
return componentExist(value) ? '组件名 或 views名已经存在' : true
}
return '请输入views 所在文件夹名称'
}
},
{
type: 'input',
name: 'name',
default: 'page',
message: '请输入 views 名称!'
},
{
type: 'confirm',
name: 'hasDialog',
default: true,
message: '是否须要 编辑弹窗 组件?'
},
{
type: 'confirm',
name: 'hasApi',
default: true,
message: '是否添加 api 配置文件?'
},
{
type: 'confirm',
name: 'hasVuex',
default: true,
message: '是否添加 vuex moudule 文件?'
}
],

actions: data => {
const { hasDialog, hasApi, hasVuex, name, dir } = data
const actions = []

actions.push({
type: 'add',
path: '../src/views/{{kebabCase name}}/{{properCase name}}.vue',
templateFile: './view/view.hbs'
})

if (hasDialog) {
actions.push({
type: 'add',
path: '../src/views/{{kebabCase name}}/components/{{properCase name}}Dialog.vue',
templateFile: './view/dialog.hbs'
})
actions.push({
type: 'add',
path: '../src/views/{{kebabCase name}}/components/index.js',
templateFile: './view/components.hbs'
})
}
if (hasApi) {
actions.push(data => {
const { name } = data
const cmd = `npm run g api ${dir} ${name}`
exec(cmd, (err, res, stderr) => {
if (err || stderr) return err || stderr
process.stdout.write(res)
})
return '已添加 api 配置文件'
})
}
if (hasVuex) {
actions.push(_ => {
const cmd = `npm run g vuex ${name}`
exec(cmd, (err, res, stderr) => {
if (err || stderr) {
return err || stderr
}
process.stdout.write(res)
})
return '已添加 vuex modules 配置文件'
})
}

return actions
}
}
复制代码

完整示例请参考项目地址顺便求个start

最后说两句

上述只是一个简单配置,项目中能够根据项目特色进行模板定制,从而提高工做效率。
若是你有更好的建议欢迎留言评论,你们共同交流学习,共同进步。若是看完后,以为对你有用欢迎、点赞、评论、分享!!!谢谢!!!

另外,我也开通了我的公众号,欢迎关注!!!

禾寸 欢迎关注!喜欢就坚持吧!
相关文章
相关标签/搜索