Vuex 自動化生成工具

Vuex 自動化生成工具需求文檔


1. 需求背景

為提升前端開發效率,減少重復代碼編寫,需開發一個自動化工具,根據輸入參數自動生成完整的 Vuex 存儲模塊(包括api.js,mutations.js,actions.js,getters.js,mutation-types。js)。
在這里插入圖片描述


2. 功能需求
2.1 輸入參數
參數名類型必填描述示例值
apiNamestringAPI 名稱(駝峰命名)getUserInfo
apiUrlstringAPI 地址/api/user/info
remarkstring接口注釋獲取用戶詳細信息
requestTypestringHTTP 方法(默認 GET)post
apiTypestringAPI 分類get create update download

2.2 生成文件及規則
2.2.1 api.js 文件
  • 功能:存儲 API 地址常量
  • 生成規則
    /*** 獲取用戶詳細信息*/
    export const getUserInfo = '/api/user/info';
    
  • 校驗
    • 文件不存在時自動創建
    • 接口名稱或地址重復時拋出錯誤
2.2.2 mutation-types.js 文件
  • 功能:定義 mutation 類型常量
  • 生成規則
    /*** 獲取用戶詳細信息*/
    export const GETUSERINFO_REQUEST = 'GETUSERINFO_REQUEST';
    export const GETUSERINFO_RECEIVE = 'GETUSERINFO_RECEIVE';
    
2.2.3 mutations.js 文件
  • 功能:生成狀態變更邏輯
  • 生成規則
    [type.GETUSERINFO_REQUEST](state) {state.userInfoStatus = 'loading';state.userInfo = {};
    },
    [type.GETUSERINFO_RECEIVE](state, res) {state.userInfoStatus = 'loaded';state.userInfo = res?.content || {};
    }
    
2.2.4 getters.js
  • 功能:生成狀態獲取方法
  • 生成規則
    export const userInfo = state => state.userInfo || {};
    export const userInfoStatus = state => state.userInfoStatus || '';
    
2.2.5 actions.js
  • 功能:生成 API 調用邏輯
  • 生成規則
    export const getUserInfo = ({ commit }, data) => {commit(type.GETUSERINFO_REQUEST, data);return ajax.post(API.getUserInfo,{ commit },data,type.GETUSERINFO_RECEIVE);
    };
    

3. 非功能性需求
3.1 錯誤處理
  • 接口名稱/地址重復時中止操作并提示
  • 文件權限不足時拋出異常
3.2 目錄管理
  • 默認生成到 ./store/modules/ 目錄
  • 自動創建缺失的目錄層級
3.3 代碼風格
  • 統一使用 2 空格縮進
  • 自動生成 JSDoc 注釋

4. 使用示例
// 調用示例
addStoreToFile('getUser', '/api/user', '獲取用戶數據', 'get', 'user');

5. 輸出驗證

執行成功后需生成以下文件結構:

store/modules/api.jsmutations.jsgetters.jsactions.jsmutation-types.js

基礎代碼

const fs = require('fs');
const path = require('path');
const BASE_DIR = './store/user'; // 所有文件生成到store/modules下
const apiFilePath = `${BASE_DIR}/api.js`
const mutationsFilePath = `${BASE_DIR}/mutations.js`
const actionsFilePath = `${BASE_DIR}/actions.js`
const mutationTypesFilePath = `${BASE_DIR}/mutation-types.js`
const gettersFilePath = `${BASE_DIR}/getters.js`
// 校驗文件內是否已經存在
function _checkCorrect(filePath, regStr, apiUrl) {// 1. 檢查文件是否存在if (!fs.existsSync(filePath)) {fs.writeFileSync(filePath, '', 'utf8');}// 2. 讀取文件內容const content = fs.readFileSync(filePath, 'utf8');// 3. 檢查接口是否已存在const apiRegex = new RegExp(regStr, 'g');if (regStr && apiRegex.test(content)) {throw new Error(`已存在`);return false}// 4. 檢查URL是否已存在if (apiUrl && content.includes(apiUrl)) {throw new Error(`接口地址 ${apiUrl} 已存在`);return false}return true
}
// 匹配是否滿足條件的函數
function _checkFunctionExists(content, apiName) {// 匹配兩種函數定義方式:// 1. export const fnName = ({ commit }) => {...}// 2. export function fnName({ commit }) {...}const funcRegex = new RegExp(`export\\s+(?:const\\s+${apiName}\\s*=\\\s*\\(|function\\s+${apiName}\\s*\\\()`);return funcRegex.test(content);
}
// 重新設置名稱
function _getNewApiName(apiName, requestType, apiType) {if (apiType) {// 將apiName首字母大寫apiName = apiName.replace(apiName[0], apiName[0].toUpperCase())apiName = requestType == 'get' ? (requestType + apiName) : (apiType + apiName)return apiName}return apiName
}
// 在文件頂部添加創建目錄的函數
function _ensureDirectoryExists() {if (!fs.existsSync(BASE_DIR)) {fs.mkdirSync(BASE_DIR, { recursive: true });}
}
// 1. api寫入
function addApiToFile(apiName, apiUrl, remark = '', requestType, apiType) {let filePath = `${BASE_DIR}/api.js`let isCorrect = _checkCorrect(apiFilePath, `export const ${apiName} *= *['"].+['"]`, apiUrl)if (isCorrect) {const newApi = `
/*** ${remark} */
export const ${apiName} = '${apiUrl}';\n`;fs.appendFileSync(apiFilePath, newApi, 'utf8');return `接口 ${apiName} 添加成功`;}}
// 2. mutation-types寫入
function addMutationTypes(apiName, remark) {apiName = apiName.toUpperCase()let isCorrect1 = _checkCorrect(mutationTypesFilePath, `export const ${apiName + '_REQUEST'} *= *['"].+['"]`)let isCorrect2 = _checkCorrect(mutationTypesFilePath, `export const ${apiName + '_RECEIVE'} *= *['"].+['"]`)if (isCorrect1 && isCorrect2) {let newApi = `
/*** ${remark} */
export const ${apiName + '_REQUEST'} = '${apiName + '_REQUEST'}';\n
export const ${apiName + '_RECEIVE'} = '${apiName + '_RECEIVE'}';\n`;fs.appendFileSync(mutationTypesFilePath, newApi, 'utf8');return `mutation-types ${apiName} 添加成功`;}
}
//3. getters 寫入
function addGettersToFile(apiName, remark) {let isCorrect1 = _checkCorrect(gettersFilePath, `export const ${apiName + 'Info'} *= *['"].+['"]`)let isCorrect2 = _checkCorrect(gettersFilePath, `export const ${apiName + 'Status'} *= *['"].+['"]`)if (isCorrect1 && isCorrect2) {let newApi = `
/*** ${remark} */
export const ${apiName + 'Info'} = state =>state[${apiName + 'Info'}]||{};\n
export const ${apiName + 'Status'} = state =>state[${apiName + 'Status'}]||'';\n`;fs.appendFileSync(gettersFilePath, newApi, 'utf8');return `getters ${apiName} 添加成功`;}
}
// 4. mutations 寫入
function addMutationsToFile(apiName, remark) {// 1. 初始化文件(如果需要)if (!fs.existsSync(mutationsFilePath)) {fs.writeFileSync(mutationsFilePath, `
import * as type from './mutation-types'
export const state = {}
export const mutations = {}`.trim(), 'utf8');}// 2. 讀取最新內容(每次重新讀取)let content = fs.readFileSync(mutationsFilePath, 'utf8');// 3. 處理stateconst stateRegex = /export\s+const\s+state\s*=\s*{([^{}]*?(?:\{[^{}]*\}[^{}]*?)*)}/ ///export\s+const\s+state\s*=//\s*{([\s\S]*?)}/;if (stateRegex.test(content)) {content = content.replace(stateRegex, (match, stateContent) => {if (new RegExp(`${apiName}Info\\s*:|${apiName}Status\\s*:`).test(stateContent)) {throw new Error(`State中已存在${apiName}相關屬性`);}return `export const state = {${stateContent.trim()}${remark ? `// ${remark}` : ''}${apiName}Info: {},${apiName}Status: '',
}`;});}// 4. 處理mutations(關鍵修正)const mutationRegex = /export\s+const\s+mutations\s*=\s*{([\s\S]*?)}\s*$/;if (mutationRegex.test(content)) {content = content.replace(mutationRegex, (match, mutationContent) => {if (new RegExp(`\\[type\\.${apiName.toUpperCase()}_(REQUEST|RECEIVE)\\]`).test(mutationContent)) {throw new Error(`Mutations中已存在${apiName}相關操作`);}return `export const mutations = {${mutationContent.trim()}${remark ? `// ${remark}` : ''}[type.${apiName.toUpperCase()}_REQUEST](state) {state.${apiName}Status = 'loading';state.${apiName}Info = {};},[type.${apiName.toUpperCase()}_RECEIVE](state, res) {state.${apiName}Status = 'loaded';state.${apiName}Info = res?.content || {};},
}`;});}// 5. 寫入最終結果fs.writeFileSync(mutationsFilePath, content, 'utf8');return `${apiName}相關mutations配置已添加`;
}
//5. actions.js
function addActionsToFile(apiName, remark, requestType) {// 1. 初始化文件(如果需要)if (!fs.existsSync(actionsFilePath)) {fs.writeFileSync(actionsFilePath, `
import * as type from './mutation-types'
import * as API from './api'
import { ajax } from '@/utils/fetch'`.trim(), 'utf8');}// 2. 讀取最新內容(每次重新讀取)let content = fs.readFileSync(actionsFilePath, 'utf8');// 3. 判斷文件中是否存在函數名稱為apiName的函數if (_checkFunctionExists(content, apiName)) {throw new Error(`函數 ${apiName} 已存在`);}// 4. 追加新函數const newAction = `
${remark ? `// ${remark}` : ''}  export const ${apiName} = ({ commit }, data) => {commit(type.${apiName.toUpperCase()}_REQUEST, data);return ajax.${requestType}(API.${apiName},{ commit },data,type.${apiName.toUpperCase()}_RECEIVE);};`;fs.appendFileSync(actionsFilePath, newAction, 'utf8');return `${apiName}相關actions配置已添加`;}// apiType:['get', 'create', 'download', 'update', 'delete']
function addStoreToFile(apiName, apiUrl, remark = '', requestType = 'get', apiType) {_ensureDirectoryExists()let newApiName = _getNewApiName(apiName, apiType)// 1. 添加 APIaddApiToFile(newApiName, apiUrl, remark,)// 2. 添加 addMutationTypesaddMutationTypes(apiName, remark)// 3. 添加 gettersaddGettersToFile(apiName, remark)// 4. 添加 mutationsaddMutationsToFile(apiName, remark)// 5. 添加 actionsaddActionsToFile(newApiName, remark, requestType)return 'success'}try {// console.log(addStoreToFile('getName', 'api/user/name', '獲取名稱'));// console.log(addStoreToFile('getUser', 'api/user/User', '獲取用戶信息'));console.log(addStoreToFile('getStore1', 'api/user/store1', '獲取用戶信息', 'post'));} catch (error) {console.error(error.message);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84461.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84461.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84461.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入淺出多路歸并:原理、實現與實戰案例解析

文章目錄 二路歸并多路歸并方法一:指針遍歷(多指針比較法)方法二:小根堆法(最小堆歸并) 實際場景外部排序 經典題目丑數Ⅱ方法一:三指針法方法二:優先隊列法(K路歸并&…

Koji構建系統宏定義注入與Tag體系解析

在Red Hat生態的持續集成鏈條中,Koji作為核心構建系統,其靈活的宏定義機制與精密的Tag體系是保障軟件包高效流轉的關鍵。本文將系統闡述在既有構建目標中注入宏定義的技術路徑,并深度解析Koji中Target與Tag的概念架構及其版本演進差異。 一、…

【Kubernetes】架構與原理:核心概念、組件協同及容器化部署解析

文章目錄 一、前言二、為什么需要 Kubernetes1. 傳統部署方法2. 虛擬化部署3. 容器化部署Ⅰ. 基本概念Ⅱ. 容器編排的必要性Ⅲ. 容器化部署的優勢4. k8s 的歷史與發展三、Kubernetes 基本概念1. k8s 核心架構解析Ⅰ. 控制平面與工作節點Ⅱ. 各組件協同工作原理2. k8s 核心概念Ⅰ…

Pip Manager本地Python包管理器

在Python開發領域,包管理是每個開發者日常工作中不可或缺的一部分。雖然命令行工具pip功能強大,但對于初學者和非技術背景的用戶來說,命令行界面往往顯得不夠友好。如果使用PyCharm,則可以非常簡單的管理安裝的Python包&#xff1…

vscode界面設置透明度--插件Glasslt-VSC

【快捷鍵:透明度提高(CtrAlt Z),透明度降低(CtrAlt C)】

OPENCV形態學基礎之一膨脹

一.膨脹的原理 數學表達式:dst(x,y) dilate(src(x,y)) max(x,y)src(xx,yy) 膨脹是圖像形態學的基本功能之一,膨脹顧名思義就是求圖像的局部最大值操作,它的數學表達式是dst(x,y) dilate(src(x,y)) max(x,y)src(xx,yy)。 從數學的角度來看…

徹底禁用Windows Defender通知和圖標

方法 一:通過注冊表強制隱藏 Defender 圖標(永久生效)?? (適用于徹底隱藏圖標,但需謹慎操作) ??打開注冊表編輯器?? 按 Win R,輸入 regedit 回車。 ??導航到 Defender 相關注冊表項?…

Kafka 2.7.0 單節點安裝與啟動教程(適配 JDK 1.8)

1. 下載與解壓 官方下載 Kafka 2.7.0 https://archive.apache.org/dist/kafka/2.7.0/kafka_2.13-2.7.0.tgz 上傳到虛擬機(如 /home/wang/soft/kafka)解壓: tar -zxvf kafka_2.13-2.7.0.tgz 2. 配置環境變量(可選,便…

23、Python字符串核心機制解析:駐留原理、對象比較與成員檢測實戰

適合人群:零基礎自學者 | 編程小白快速入門 閱讀時長:約5分鐘 文章目錄 一、問題:Python的字符串駐留機制?1、例子1:字符串駐留現象2、答案:(1)字符串駐留 二、問題:Pyth…

pikachu靶場通關筆記22-2 SQL注入05-2-update注入(報錯法)

目錄 一、SQL注入 二、update注入 三、報錯型注入 四、源碼分析 1、代碼審計 2、滲透思路 五、滲透實戰 1、滲透準備 2、獲取數據庫名database 3、獲取表名table 4、獲取列名column 5、獲取字段 本系列為通過《pikachu靶場通關筆記》的SQL注入關卡(共10關&#xff…

【prometheus+Grafana篇】基于Prometheus+Grafana實現Redis數據庫的監控與可視化

💫《博主主頁》: 🔎 CSDN主頁 🔎 IF Club社區主頁 🔥《擅長領域》:擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控;并對SQLserver、NoSQL(MongoDB)有了…

R語言速釋制劑QBD解決方案之四

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》速釋制劑混合和潤滑工藝研究的R語言解決方案。 原料粒徑分布與混合次數對混合均一性的影響 由于acetriptan 的溶解度低,acetriptan 需要粉碎以提高生物利用度。粉碎后的原料…

用python玩轉大語言模型——從 RNN 到文本生成大語言模型的奇幻之旅

用python玩轉大語言模型——從 RNN 到文本生成大語言模型的奇幻之旅 第一部分:RNN原理及其結構(魔法師的記憶水晶球) 1.1 經典RNN結構(時光旅行者的備忘錄) 核心概念 時間循環:RNN通過隱藏狀態h在時間步之間傳遞信息,形成閉環結構參數共享:每個時間步使用相同的權重…

數據結構(9)排序

一、常見排序算法 排序在生活中無處不在,上學這么多年班級排名啥的總有吧,不可能一次都沒見過;打游戲有的排行榜不也是有排序的思想在里面,排序倒不是什么特殊的數據結構,但是是非常重要的算法思想,所以在初…

量子計算導論課程設計 之 PennyLane環境搭建

文章目錄 具體配置conda 虛擬環境配置Pennylane 正所謂,磨刀不誤砍柴工,想要進行量子計算導論的課程設計,首先就是搭建好平臺,推薦大家就是本地搭建,那么下面有三種選擇 QiskitTensorFlow QuantumPennylane 具體配置…

nginx ./nginx -s reload 不生效

問題 nginx ./nginx -s reload 不生效 解決 不是改opt/nginx下的配置文件是改/usr/local/nginx下的配置文件改之前做好備份

建造者模式深度解析與實戰應用

作者簡介 我是摘星,一名全棧開發者,專注 Java后端開發、AI工程化 與 云計算架構 領域,擅長Python技術棧。熱衷于探索前沿技術,包括大模型應用、云原生解決方案及自動化工具開發。日常深耕技術實踐,樂于分享實戰經驗與…

VScode - 我的常用插件01 - 主題插件Noctis

導言 Noctis 是一款為 Visual Studio Code 提供的主題插件,主打高對比度、護眼、美觀。它有多種配色風格,適合不同的開發者審美和工作場景。 一、安裝Noctis 二、設置顏色主題 三、測試主題 如上所示,有11種主題背景可以選擇。這里&#xff…

【IQA技術專題】圖像質量評價IQA技術和應用綜述(萬字長文!!)

專題介紹 圖像質量評價(Image Quality Assessment, IQA)是圖像處理、計算機視覺和多媒體通信等領域的關鍵技術之一。IQA不僅被用于學術研究,更在影像相關行業內實現了完整的商業化應用,涉及影視、智能手機、專業相機、安防監控、…

突然虛擬機磁盤只剩下幾十K

第一步:查找哪些文件大于 100M find / -size 100M 第二步:刪除掉無用的 log 發現,磁盤剩余空間并沒有變大 假如一個文件正在被使用,你刪除之后也是不會釋放存儲空間的。需要關閉相應的服務才能釋放。