vue3 pinia admin开发日志

vue3 pinia admin开发日志

初始化项目

// 使用 npm
npm create vite
// 使用yarn
yarn create vite
// 使用pnpm
pnpm create vite

创建完成后进入项目文件夹安装依赖

// 使用 npm
npm install
// 使用yarn
yarn install
// 使用pnpm
pnpm install

649d91201ddac507ccd49f7e.png

接下来清空项目

649d916b1ddac507ccd53c3d.png

649d918a1ddac507ccd579fc.png

649d91a21ddac507ccd5a568.png

vscode插件准备

649d91b81ddac507ccd5cc3b.png

配置项目

配置别名

为src配置一个别名,避免开发过程中使用 ./ ../ 之类的形式引用。

在项目根目录的 vite.config.js 中添加 alias

649d91d81ddac507ccd60bcb.png

环境变量

在项目根目录创建.env文件,以便后续使用通过import.meta.env的形式使用

VITE_BASE_URL= /
VITE_HISTORY_ROUTER="hash"

安装vue-router 、pinia和axios

649d920c1ddac507ccd668e0.png

创建文件夹

将 src 下的文件夹结构改成如下图所示

649d92201ddac507ccd68fa3.png

src
|----api  				//接口封装
|----assets  			//引入资源
|----components 		//二次封装组件
|----directives 		//自定义指令
|----layout 			//公共组件
|----plugins 			//插件
|----router				//路由
|----store				//状态管理
|----style				//样式
|----utils				//工具函数
|----views				//页面

创建配置文件

在项目根目录有个 public 文件夹,这是在这个文件夹内的文件不会被打包,所以我们要在这里放个文件,来实现前端更新时通知客户端刷新浏览器

// serverConfig.json
{
    "Version": "0.0.1"
}

除了Version版本号以外,可以包含其他字段。这些字段将在vue初始化之前被读取

获取配置

在vue初始化之前获取配置内容,因此,我们需要一个工具函数

649d92411ddac507ccd6ca92.png

然后对 main.ts中初始化流程进行更改

649d92601ddac507ccd70085.png

注册pinia

在@/store/index.ts中

import { createPinia } from "pinia";
const store = createPinia();
export { store };

然后在main.ts 中引入并注册 store

649d92721ddac507ccd71f7f.jpg

使用pinia

store/modules/app.ts 举例

import { defineStore } from "pinia";
import { store } from "@/store";
type appType = {
  routes: Array<{
    path: string;
    name: string;
    meta: { showLink?: boolean; title?: string };
    children?: Array<any>;
  }>;
};
export const useAppStore = defineStore({
  id: "app",
  state: (): appType => ({
    routes: [],
  }),
  actions: {
    SET_ROUTES(routes: Array<any>) {
      this.routes.length = 0;
      routes.forEach((value) => {
        this.routes.push(value);
      });
    },
    ADD_ROUTES(routes: Array<any>) {
      routes.forEach((value) => {
        this.routes.push(value);
      });
    },
  },
});
export function useAppStoreHook() {
  return useAppStore(store);
}

在vue组件外使用时调用 useAppStoreHook钩子函数,在vue组件内则直接使用useAppStore

注册vue-router

router/index.ts

import { createWebHashHistory, createWebHistory } from "vue-router";
import { asyncRoutes } from "./routes";
const whiteList = ["/login"];//添加登录页到白名单
const routes = asyncRoutes;
const router = createRouter({
  history:
    import.meta.env.HISTORY_MODE === "hash"
      ? createWebHashHistory()
      : createWebHistory(),
  routes,
  strict: true,
});
export default router;

引入路由

router/routes/index.ts

import basicRoute from "./basic";
import {
  ascending,
  buildHierarchyTree,
  formatTwoStageRoutes,
  formatFlatteningRoutes,
} from "@/utils";
import { useAppStoreHook } from "@/store/modules/app";
import type { RouteRecordRaw, RouteComponent } from "vue-router";
/**
 * 自动导入静态路由
 */
const modules: Record<string, any> = import.meta.glob(["./modules/**/*.ts"], {
  eager: true,
});
const routerModuleList: any[] = [];

Object.keys(modules).forEach((key) => {
  const mod = modules[key].default || {};
  const modList = Array.isArray(mod) ? [...mod] : [mod];
  routerModuleList.push(...modList);
});
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
  formatFlatteningRoutes(buildHierarchyTree(ascending(routerModuleList)))
);
/** 用于渲染菜单,保持原始层级 */
export const constantMenus: Array<RouteComponent> = ascending(
  routerModuleList
).concat(...basicRoute);
useAppStoreHook().SET_ROUTES(constantMenus);
export const asyncRoutes = [...constantRoutes, ...basicRoute];

router/routes/basic.ts基础路由

export default [
  {
    path: "/login",
    name: "Login",
    component: () => import("@/views/login/login.vue"),
    meta: {
      title: "login",
      showLink: false,
      rank: 101,
    },
  },
  {
    path: "/redirect",
    component: () => import("@/layout/index.vue"),
    meta: {
      title: "home",
      showLink: false,
      rank: 102,
    },
    children: [
      {
        path: "/redirect/:path(.*)",
        name: "Redirect",
        component: () => import("@/layout/redirect.vue"),
      },
    ],
  },
  {
    path: "/empty",
    name: "Empty",
    component: () => import("@/views/empty/empty.vue"),
    meta: {
      title: "empty",
      showLink: false,
      rank: 103,
    },
  },
];

router/routes/modules/home.ts 主页路由

import Home from "@/layout/index.vue";
export default {
  path: "/",
  name: "Home",
  component: Home,
  meta: {
    title: "首页",
    showLink: true,
    rank: 0,
  },
  redirect: "/welcome",
  children: [
    {
      path: "/welcome",
      name: "Welcome",
      component: () => import("@/views/home/welcome/welcome.vue"),
      meta: {
        title: "首页",
      },
    },
    {
      path: "/dashboard",
      name: "Dashboard",
      component: () => import("@/views/home/dashboard/dashboard.vue"),
      meta: {
        title: "看板",
      },
    },
    {
      path: "/workbench",
      name: "Workbench",
      component: () => import("@/views/home/workbench/workbench.vue"),
      meta: {
        title: "工作台",
      },
    },
  ],
} as routerConfig;

配置自动引入与自动注册

安装依赖

npm i -D unplugin-auto-import unplugin-icons unplugin-vue-components

在vite.config.ts中引入

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
export default defineConfig(({ mode }) => {
  return {
      plugins:[
          AutoImport({//自动引入
              	dts:"types/auto-import.d.ts"//声明文件输出位置
          		resolvers:[
              	ElementPlusResolver(),
          		IconResolver({
                    prefix:"Icon"
                }),
          	imports:["vue","vue-router"]//需要全局引入的包
              ]
          }),
        Components({//自动注册
        dts: "types/components.d.ts",//声明文件输出位置
        resolvers: [
          ElementPlusResolver(),
          IconsResolver({ enabledCollections: ["ep"] }),
        ],
      }),
      Icons({// 引入图标
        autoInstall: true,
      }),
      ]
  }

css预处理器

vue脚手架默认支持css预处理器,只需引入即可使用

使用何种预处理器一般取决于组件库的css预处理器

原子化css

什么是原子化css

原子化 CSS(Atomic CSS):

原子化 CSS 是一种 CSS 的架构方式,它倾向于小巧且用途单一的 class,并且会以视觉效果进行命名;有些人可能会称其为函数式 CSS,或者 CSS 实用工具。本质上,可以将原子化的 CSS 框架理解为这类 CSS 的统称

相关框架

tailwindcss

windicss

unicss

附录

vue3 pinia admin开发日志
https://pic.imgdb.cn/item/64fa9601661c6c8e54915ac6.webp
作者
Firefly
发布于
2026-04-03
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Firefly
Hello, I'm Firefly.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
暂无封面

音乐

暂未播放

0:000:00
暂无歌词
暂无歌曲
分类
标签
站点统计
文章
21
分类
3
标签
13
总字数
57,102
运行时长
601
最后活动
143 天前

目录