基於vuex動態添加接口(含axios的封裝)

當項目過大時會存在不少接口,並且不一樣人寫不一樣的接口很不方便管理,這裏能夠定義在json文件裏面定義接口,而後經過模板生成相應的文件,這樣會方便管理和閱讀,在根目錄定義一個coder文件夾,定義一個schema.json文件,先來看看定義的接口json文件以下:vue

{
    "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以下:node

image.png

先看看index.js文件ios

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文件ajax

// 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文件vuex

// 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

image.png

而後就是運行npm run coder,運行後會在src的store下types.js和modules.js文件,以及store文件夾下的code文件夾下的幾個文件,文件個數和json下的數組個數相關,文件名稱以json文件裏面的name屬性相關,具體代碼能夠看index.js,代碼結構以下:json

image.png

相關代碼以下:axios

//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文件數組

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文件,也就是引入modulesapp

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就能夠自動生成相應文件,而後像上面同樣調用就能夠了

相關文章
相關標籤/搜索