每天搬砖,也早已变成了cv工程师。频繁的复制粘贴,复制完成后再删除,枯燥且无聊。项目中咱们一般在编辑器中配置快捷键生成代码片断。好像这些也知足不了cv的欲望。在项目中配置业务相关的一些模板文件,而后动态生成文件,显得尤其重要。不受编辑器的限制,更好的自定义配置,显得更为强大。html
其实,生成代码片断的方式有不少,好比在代码编辑器中配置快捷键,就能够生成代码片断。好比在 vscode 里面安装插件也能够。虽然编辑器能够实现,可是不可以更加自定义。vue
在大型项目中,好多页面都是比较类似的,代码层面基本相似,一般新建一个页面组件,须要复制以前的一个页面、复制api配置文件、复制store中的文件,而后改一下相关变量,每每还会有漏改的状况。node
如今咱们能够将这部分代码的公共部分进行抽离作成一个模板文件,经过询问的方式获取是否须要添加部分代码片断。经过判断,而后生成的相应文件。这样咱们就能够造成一个该项目特有的通用代码的生成方式,提升工做效率妥妥的。git
主要步骤:github
这里使用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
我配置了四种命令:
// 引入各模块配置文件
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
的模块中,主要是生成一个 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
转化为小驼峰的格式。
经常使用的还有下面的关键词,能够格式化用户输入参数:
更多关键词,请查看相关文档点击查看
首先预览下效果:
在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
所在文件夹名称!
在该询问中,添加了重名验证,在输入重复名称时,会提示而且能够从新输入文件夹名称。保存用户输入至 dir
变量中。
请输入 views
名称!
和以前的的配置没有什么区别,主要获取新建的文件名称。保存至变量 name
中。
是否须要 编辑弹窗 组件!
将用户选择结果保存在 hasDialog
中,这样就能够在 actions
中根据 hasDialog
进行动态判断生成 action
。
是否添加 api 配置文件?
将用户选择结果保存在 hasApi
中,而后在 actions
中进行判断。此处能够直接执行已经配置好的命令来生成。这里使用 node
中的 child_process.exec
函数执行命令 npm run g api ${dir} ${name}
便可。
vuex moudule
文件?
同理根据 hasVuex
的值,执行 npm run g vuex ${name}
命令便可
在 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
上述只是一个简单配置,项目中能够根据项目特色进行模板定制,从而提高工做效率。
若是你有更好的建议欢迎留言评论,你们共同交流学习,共同进步。若是看完后,以为对你有用欢迎、点赞、评论、分享!!!谢谢!!!
另外,我也开通了我的公众号,欢迎关注!!!