当项目过大时会存在很多接口,而且不同人写不同的接口很不方便管理,这里可以定义在json文件里面定义接口,然后通过模板生成相应的文件,这样会方便管理和阅读,在根目录定义一个coder文件夹,定义一个schema.json文件,先来看看定义的接口json文件如下:
{
"doc": {
"models": {
"sooKey": [
{
"title": "菜单",
"path": "/menu/getMenu",
"methods": false,
"name": "getMenu",
"state": "getMenu",
"httpMethod": "post"
},
{
"title": "哎呦不错呦12",
"path": "xtztc/info/key12",
"methods": false,
"name": "getScriptPeple",
"state": "getScriptPeple",
"httpMethod": "post"
}
],
"myTest": [
{
"title": "测试",
"path": "/menu/getTitle",
"methods": false,
"name": "getTitle",
"state": "getTitle",
"httpMethod": "post"
}
]
}
}
}
上面定义的文件中title为描述接口的描述,path为接口路径,name定义接口的方法,httpMethod为请求的方法,每个数组相当于一个模块下的接口,这里以post为演示,在coder文件下定义一个index.js文件,创建一个templates文件夹,在templates文件夹下创建两个文件分别是:types.js和store.js如下:
先看看index.js文件
const fs = require('fs')
const path = require('path')
// 引入遍历插件
const _ = require('lodash')
// const rm = require('rimraf')
// 引入接口文档
const SCHEMA = require('./schema.json')
const beautify = require('js-beautify').js_beautify
// 导入生产types模板
const typesRender = require('./templates/types')
//导入生成store的模板
const storeRender = require('./templates/store')
// 配置文件
const config = {
// 生成store文件路径
outStorePath: '../src/store/coder/',
// 生成store配置文件路径
outStoreType: '../src/store/',
}
// const MODELS = parseSchemas(SCHEMA.doc.models || {})
// json文件赋值
const MODELS = SCHEMA.doc.models || {};
/**
* 创建文件
* @param path
* @param fileName
* @param content
*/
function writeFile (path, fileName, content) {
if (!fs.existsSync(path)) {
fs.mkdirSync(path)
}
fs.writeFileSync(path + toKebabCase(fileName) + '.js', content, {encoding: 'utf8'})
}
// 大小写转换
function toUpperCase (name) {
return name.toUpperCase()
}
/**
* Foo Bar | --foo-bar | __foo_bar__ => fooBar
* @param name
*/
function toCamelCase (name) {
return _.camelCase(name)
}
/**
* Foo Bar | fooBar | --foo-bar => foo_bar
* @param name
*/
function toSnakeCase (name) {
return _.snakeCase(name)
}
/**
* fooBar => foo-bar
* @param name
*/
function toKebabCase (name) {
return _.kebabCase(name)
}
function toUpperSnakeCaseName (name) {
return toUpperCase(toSnakeCase(name))
}
/**
* 格式化js代码
* @param content
* @returns {*}
*/
function beautifyJs (content) {
content = content.replace(/(\r\n|\n)\s*/g, '\n')
.replace(/\(\n/g, '(')
.replace(/,\n/g, ',')
.replace(/\/\*\*/g, '\n/**')
.replace(/\n\/\//g, '\n\n//')
return beautify(content, {
indent_with_tabs: false,
indent_size: 2,
jslint_happy: true,
end_with_newline: true,
space_after_anon_function: true
})
}
/**
* 生成store文件
*/
function writeStore () {
// 定义types模板的数据
let types = {}
//定义modules.js的数据和modules.js导出的字段
let modules = [], extendsArray = []
// 遍历json文件
_.each(MODELS, function (model, name) {
modules.push(`import ${name} from './coder/${ toKebabCase(name)}'`)
extendsArray.push(name)
let importTypeArray = [],
customStateArray = [],
items = []
types[name] = []
_.each(model, function (item) {
types[name].push({
name: toUpperSnakeCaseName(item.name)
})
importTypeArray.push(toUpperSnakeCaseName(item.name))
customStateArray.push(item.state)
items.push({
NAME: toUpperSnakeCaseName(item.name),
name: toCamelCase(item.name),
state: item.state,
url: item.path,
httpMethod: item.httpMethod,
ajaxParam: 'data'
})
})
// 定义生成文件的路径
const outPath = path.join(__dirname, config.outStorePath)
console.log(items, 'itemsitemsitems');
// 生成store模板文件并传值
writeFile(outPath, name, beautifyJs(storeRender({
name: name,
kebabCaseName: toKebabCase(name),
importTypeArray: importTypeArray,
customStateArray: customStateArray,
items: items
})))
});
// 定义生成文件的路径
const outStore = path.join(__dirname, config.outStoreType)
// 生成types模板文件并传值
writeFile(outStore, 'types', beautifyJs(typesRender({types: types})))
modules.push(`export default {${extendsArray.join(', ')}}`)
// 生成modules模板文件并传值
writeFile(outStore, 'modules', modules.join('\n') + '\n')
}
function init() {
// 初始化
// console.log(SCHEMA, 'asd');
console.log('开始生成代码.....')
writeStore();
console.log('代码构建完成.....')
}
init()
然后是templates下的types.js文件和store.js文件
// types.js文件
const _ = require('lodash')
module.exports = _.template(`
<%_.each(types, function(items, name){%>
// <%=name%>
<%_.each(items, function(item){%>
export const <%=item.name%> = '<%=item.name%>'
<%})%>
<%})%>
`)
// store.js文件
const _ = require('lodash')
module.exports = _.template(`
/*! build time: <%=new Date().toLocaleString()%> */
// <%=importTypeArray.join(', ')%>
import { <%=importTypeArray.join(', ')%> } from '../types'
import axios from "axios"
// store module
export default {
actions: {
<%_.each(items, function(item, i){%>
<%if(i>0){%>,<%}%>
<%if(item.httpMethod == 'post'){%>
[<%=item.NAME%>]({commit},
<%_.each(item.params, function(param){%>
<%=param%>,
<%})%>
<%=item.ajaxParam%>
={}) {
return new Promise(function(resolve, reject){
axios.post('<%=item.url%>',<%=item.ajaxParam%>).then(data=>{
resolve(data)
})
});
}
<%}%>
<%})%>
}
}
`)
然后就是运行index.js文件,在package.json文件的scripts下添加一行"coder": "node coder/index.js"如下:
然后就是运行npm run coder,运行后会在src的store下types.js和modules.js文件,以及store文件夹下的code文件夹下的几个文件,文件个数和json下的数组个数相关,文件名称以json文件里面的name属性相关,具体代码可以看index.js,代码结构如下:
相关代码如下:
//soo-key.js文件,这里用到了vuex的action和modules
/*! build time: 2019-1-8 16:20:44 */
// GET_MENU, GET_SCRIPT_PEPLE
import {
GET_MENU,
GET_SCRIPT_PEPLE
} from '../types'
import axios from "axios"
// store module
export default {
actions: {
[GET_MENU]({
commit
},
data = {}) {
return new Promise(function (resolve, reject) {
axios.post('/menu/getMenu', data).then(data => {
resolve(data)
})
});
},
[GET_SCRIPT_PEPLE]({
commit
},
data = {}) {
return new Promise(function (resolve, reject) {
axios.post('xtztc/info/key12', data).then(data => {
resolve(data)
})
});
}
}
}
types.js文件
// sooKey
export const GET_MENU = 'GET_MENU'
export const GET_SCRIPT_PEPLE = 'GET_SCRIPT_PEPLE'
// myTest
export const GET_TITLE = 'GET_TITLE'
modules.js文件
import sooKey from './coder/soo-key'
import myTest from './coder/my-test'
export default {sooKey, myTest}
然后就是src下的store.js文件,也就是引入modules
import Vue from 'vue';
import Vuex from 'vuex'
// 引入modules文件
import modules from './modules'
import usually from './usually'
import getters from './getters'
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
...modules,
usually
},
getters: {
...getters
}
})
使用方法,在相应组件下引入import {GET_MENU} from "../../store/types";
this.$store.dispatch(GET_MENU, {asd:10}).then((res)=>{
console.log(res, 'resresresres');
this.menuList = res.data.msg;
// console.log(this.menuList, 'this.menuListthis.menuListthis.menuList');
});
总结:以后不管是谁只要添加接口,只要在schema.json文件下添加相应的接口,然后直接运行npm run coder就可以自动生成相应文件,然后像上面一样调用就可以了