騷年,請不要手敲 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

最後說兩句

上述只是一個簡單配置,項目中能夠根據項目特色進行模板定製,從而提高工做效率。
若是你有更好的建議歡迎留言評論,你們共同交流學習,共同進步。若是看完後,以爲對你有用歡迎、點贊、評論、分享!!!謝謝!!!

另外,我也開通了我的公衆號,歡迎關注!!!

禾寸 歡迎關注!喜歡就堅持吧!
相關文章
相關標籤/搜索