博客 / 詳情

返回

老闆:能不能別手動複製路由了?我:寫個腳本自動掃描

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

起因

週五快下班,老闆過來看權限配置頁面。

"這個每次都要手動輸路徑?"

"對,現在是這樣。"我打開給他看:

角色:運營專員
路由路徑:[手動輸入] /user/list
組件路徑:[手動輸入] @/views/user/List.vue

"上次運營配錯了,/user/list 寫成 /user/lists,頁面打不開找了半天。能不能做個下拉框,直接選?"

我想了想:"可以,但得先有個頁面列表。"

"那就搞一個,現在頁面這麼多,手動輸容易出錯。"

確實,項目現在幾十個頁面,每次配置權限都要翻代碼找路徑,複製粘貼,還擔心複製錯。

解決辦法

週末琢磨了一下,其實就是缺個"頁面清單"。views 目錄下都是頁面文件,掃描一遍不就有了?

寫了個 Node 腳本,自動掃描 views 目錄,生成路由映射表。配置權限的時候下拉框選,還能搜索。

實現

兩步:掃描文件 + 生成映射。

掃描 .vue 文件

function getAllVueFiles(dir, filesList = []) {
  const files = fs.readdirSync(dir);
  
  files.forEach((file) => {
    const filePath = path.join(dir, file);
    
    if (fs.statSync(filePath).isDirectory()) {
      getAllVueFiles(filePath, filesList);  // 遞歸子目錄
    } else if (file.endsWith(".vue")) {
      filesList.push(filePath);  // 收集 .vue 文件
    }
  });
  
  return filesList;
}

生成映射文件

function start() {
  const viewsDir = path.resolve(__dirname, "../views");
  let files = getAllVueFiles(viewsDir);
  
  // 兼容 Windows 路徑
  files = files.map(item => item.replace(/\\/g, "/"));
  
  // 拼接成 import 映射
  let str = "";
  files.forEach(item => {
    let n = item.replace(/.*src\//, "@/");
    str += `"${n}":()=>import("${n}"),\r\n`;
  });
  
  // 寫入文件
  fs.writeFileSync(
    path.resolve(__dirname, "../router/all.router.js"),
    `export const ROUTERSDATA = {\n${str}}`
  );
}

最後生成的文件大概是這樣:

// src/router/all.router.js
export const ROUTERSDATA = {
  "@/views/Home.vue": () => import("@/views/Home.vue"),
  "@/views/About.vue": () => import("@/views/About.vue"),
  "@/views/user/List.vue": () => import("@/views/user/List.vue"),
}

怎麼用

權限配置頁面

<template>
  <el-select 
    v-model="selectedRoute" 
    filterable 
    placeholder="搜索並選擇頁面">
    <el-option
      v-for="(component, path) in ROUTERSDATA"
      :key="path"
      :label="path"
      :value="path">
      {{ path }}
    </el-option>
  </el-select>
</template>

<script setup>
import { ROUTERSDATA } from '@/router/all.router.js'

// 後台返回的權限路由配置
const permissionRoutes = [
  { path: '/user/list', component: '@/views/user/List.vue' },
  { path: '/order/list', component: '@/views/order/List.vue' }
]

// 直接從映射表取組件
const routes = permissionRoutes.map(route => ({
  path: route.path,
  component: ROUTERSDATA[route.component]  // 這裏直接用
}))
</script>

好處:

  • 下拉框自動包含所有頁面
  • 支持搜索,輸入 "user" 就能找到所有用户相關頁面
  • 新加頁面自動出現在列表裏

動態路由

後台返回權限配置,前端從映射表取組件:

function generateRoutes(backendConfig) {
  return backendConfig.map(item => ({
    path: item.path,
    component: ROUTERSDATA[item.component]  // 直接用
  }))
}

效果

週一把代碼提上去,改了權限配置頁面:

 

ScreenShot_2026-02-08_110740_493

 

<!-- 配置頁面 -->
<el-select v-model="route" filterable placeholder="搜索頁面">
  <el-option 
    v-for="(component, path) in ROUTERSDATA" 
    :key="path" 
    :label="path" 
    :value="path" />
</el-select>

老闆過來試了一下,在下拉框輸入 "user" 就搜到所有用户相關頁面。

"嗯,這個好用。新加頁面也會自動出現在這裏吧?"

"對,每次啓動項目會自動掃描。"

"行,那就這樣。"

後來發現還有些意外收穫:

  • 新人看這個映射表就知道項目有哪些頁面
  • 後台只存路徑字符串,數據庫乾淨
  • 順帶解決了手動 import 幾十個路由的問題

package.json 加個腳本:

{
  "scripts": {
    "dev": "node src/start/index.js && vite"
  }
}

每次 npm run dev 會先掃描 views 目錄,生成最新的映射表。

完整代碼

// src/start/index.js
const fs = require("fs");
const path = require("path");

function getAllVueFiles(dir, filesList = []) {
  const files = fs.readdirSync(dir);

  files.forEach((file) => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);

    if (stat.isDirectory()) {
      getAllVueFiles(filePath, filesList);
    } else if (file.endsWith(".vue")) {
      filesList.push(filePath);
    }
  });

  return filesList;
}

function start() {
  console.log("[自動獲取全部可顯示頁面]");

  const viewsDir = path.resolve(__dirname, "../views");
  let files = getAllVueFiles(viewsDir);

  // 統一路徑分隔符,兼容 Windows 反斜槓
  files = files.map((item) => item.replace(/\\/g, "/"));

  let str = "";
  // 構造 import 映射:"@/views/xxx.vue": ()=>import("@/views/xxx.vue")
  files.forEach((item) => {
    let n = item.replace(/.*src\//, "@/"); 
    str += `"${n}":()=>import("${n}"),\r\n`;
  });

  const routerFilePath = path.resolve(__dirname, "../router/all.router.js");
  // 將映射寫入路由聚合文件,供路由動態引用
  fs.writeFileSync(
    routerFilePath,
    `
    export const ROUTERSDATA = {
    ${str}
    }`,
  );
  console.log("[./src/router/all.router.js 寫入]");
}

start();

注意事項

記得把生成的 src/router/all.router.js 加到 .gitignore,畢竟是自動生成的文件,沒必要提交。

# .gitignore
src/router/all.router.js

後來

用了一個多月,運營配置權限再也沒出過錯。上週老闆説:"這個功能不錯,其他項目也加上。"

代碼其實挺簡單的,但確實解決了問題。

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.