# vue3项目搭建 **Repository Path**: Marimo_z/vue3-project-setup ## Basic Information - **Project Name**: vue3项目搭建 - **Description**: vue3 vite + js项目搭建全流程(axios,router,pinia,echarts,sass,element-plus部署) - **Primary Language**: HTML/CSS - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-03-26 - **Last Updated**: 2025-12-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vue3项目搭建 *vue3 vite + js项目搭建全流程(axios,router,pinia,echarts,sass,element-plus部署)* ### 一、项目初始化 ```bash npm create vite@latest my-vue-project -- --template vue cd my-vue-project npm install ``` ------ ### 二、依赖安装 ```bash npm install axios npm install vue-router@4 npm install pinia npm install pinia pinia-plugin-persistedstate npm install -D sass-embedded npm install echarts --save npm install element-plus --save npm install @element-plus/icons-vue ``` - 在 `main.js` 中挂载 ```js import { createApp } from 'vue' import App from './App.vue' /* 全局样式 */ import './style.css' /* 字体 */ import '@/assets/fonts/font.css'; /* 路由 */ import router from './router' /* 状态管理 */ import { createPinia } from 'pinia' /* pinia持久化存储 */ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' /* ElementPlus */ import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' /* ElementPlus-图标 */ import * as ElementPlusIconsVue from '@element-plus/icons-vue' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) const app = createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } app.use(pinia) app.use(router) app.use(ElementPlus) app.mount('#app') ``` ------ ### 三、项目结构建议 ```bash # 项目根目录 public/ # 静态资源目录(不会被 webpack 处理,直接复制到打包目录) ├── favicon.ico # 网站图标文件 src/ # 主开发目录 ├── api/ # API 请求模块目录(存放所有接口请求文件) ├── assets/ # 静态资源目录(会被 webpack 处理) │ ├── fonts/ # 字体文件目录 │ │ ├── font.css # 字体样式定义文件 │ │ └── typeface.ttf # 字体文件 │ ├── icons/ # SVG 图标资源目录 │ ├── images/ # 图片资源目录 │ ├── logo/ # 网站 LOGO 文件目录 │ ├── music/ # 音频文件目录 │ └── styles/ # 全局样式文件目录(可存放 scss/less/css 文件) │ ├── components/ # 公共组件目录(可复用的 Vue 组件) ├── router/ # 路由配置目录(Vue Router 配置文件) ├── stores/ # 状态管理目录(Pinia/Vuex 状态管理配置) ├── utils/ # 工具函数目录(公共方法、工具类文件) ├── views/ # 页面视图目录(路由页面组件) │ ├── 404/ # 404 页面目录 │ │ └── index.vue │ ├── home/ # 首页目录 │ │ └── index.vue │ ├── index.vue # 默认入口页面 │ └── login.vue # 登录页面组件 │ ├── App.vue # Vue 应用根组件 └── main.js # 应用入口文件(初始化 Vue 实例) # 环境变量文件 .env.development # 开发环境变量配置(本地开发使用) .env.production # 生产环境变量配置(正式部署使用) ``` ------ ### 四、环境变量 1. 开发环境配置 `.env.development` ```bash # 页面标题 VITE_APP_TITLE = 个人网页 # 开发环境配置 VITE_APP_ENV = 'development' # 开发环境地址 VITE_APP_BASE_API = '/dev-api' # websocket 开关 默认使用sse推送 VITE_APP_WEBSOCKET = false ``` 2. 生产环境配置 `.env.production` ```bash # 页面标题 VITE_APP_TITLE = 个人网页 # 生产环境配置 VITE_APP_ENV = 'production' # 生产环境地址 VITE_APP_BASE_API = '/prod-api' # websocket 开关 默认使用sse推送 VITE_APP_WEBSOCKET = false ``` ------ ### 五、重构核心配置 - 配置路径别名&跨域处理 `vite.config.js` ```js import { defineConfig, loadEnv } from 'vite'; import vue from '@vitejs/plugin-vue' import path from 'path' // 引入 path 模块 export default defineConfig(({ mode }) => { // 加载环境变量 const env = loadEnv(mode, process.cwd(), ''); return { plugins: [vue()], resolve: { alias: { '~': path.resolve(__dirname, './'), '@': path.resolve(__dirname, './src') // 将 @ 指向 src 目录 }, extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] }, server: { host: '0.0.0.0', // 监听所有可用网络接口 open: true, // 启动开发服务器时自动打开默认浏览器 proxy: { [env.VITE_APP_BASE_API]: { target: 'http://localhost:8080', // 后端地址 changeOrigin: true, ws: true, // 启用 WebSocket 代理 rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), ''), secure: false // 如果使用 HTTPS 需要设为 true } } } } }) ``` ------ ### 六、基础文件配置 1. 清除全局边距 `index.html` ```css * { padding: 0; margin: 0; } ``` 2. 设置路由出口 `App.vue` ```vue ``` 3. 首页配置 `views/index.vue` ```vue HOME 404 ``` ------ ### 七、Vue Router 配置 1. 创建路由管理文件 `src/router/index.js` ```js import { createRouter, createWebHistory } from "vue-router"; import { constantRoute } from "./routes"; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: constantRoute, // 滚动行为 scrollBehavior() { return { left: 0, top: 0 } } }); export default router; ``` 2. 创建路由文件 `src/router/routes.js` ```js // 对外暴露配置路由(常量路由) export const constantRoute = [ { // 主页 path: "/", name: "home", component: () => import("@/views/index.vue"), children: [ { path: '/home', redirect: '/' // 重定向到默认子路由 }, { path: '', // 首页(默认) name: 'HOME', component: () => import("@/views/home/index.vue") } ] }, { // 404 path: "/404", name: "404", component: () => import("@/views/404/index.vue"), }, { // 任意路由(若进入未知路由则跳转该路由) path: "/:pathMatch(.*)*", name: "Any", redirect: "/404", }, ]; ``` ------ ### 八、Pinia 状态管理 1. 创建 store 实例 `src/stores/user.js` ```js import { defineStore } from 'pinia' /* 示例 用户数据存储 */ export const useUserStore = defineStore('user', { state: () => ({ token: '', username: 'Guest', isLoggedIn: false }), actions: { login(token, username) { this.token = token this.username = username this.isLoggedIn = true }, logout() { this.token = '' this.username = 'Guest' this.isLoggedIn = false } }, persist: { enabled: true, // 开启持久化 strategies: [ { key: 'userData', // 自定义存储 key(默认使用 store id) storage: localStorage, // 指定存储方式(默认 sessionStorage) paths: ['token', 'isLoggedIn'] // 仅持久化 token 和 isLoggedIn } ] } }) ``` 2. 在 Vue 组件中操作 Store ```vue Welcome, {{ username }} (Token: {{ token }}) Logout Login ``` ------ ### 九、Axios 封装 1. 创建拦截器 `src/utils/request.js` ```js import axios from "axios"; // 创建 axios 实例 const service = axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API, // 通过环境变量配置 timeout: 50000, headers: { "Content-Type": "application/json" } }); // 请求拦截器 service.interceptors.request.use( config => { // 携带 Token 的逻辑(示例) const token = localStorage.getItem("access_token"); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => Promise.reject(error) ); // 响应拦截器 service.interceptors.response.use( response => { // 处理 2xx 状态码 const { code, message } = response.data; if (code === 200) { return response.data; // 直接返回核心数据 } else { return Promise.reject(new Error(message || "请求异常")); } }, error => { // 处理非 2xx 状态码 const status = error.response?.status; switch (status) { case 401: console.error("登录过期,请重新登录"); router.replace("/login"); break; case 403: console.error("没有权限访问"); break; case 500: console.error("服务器内部错误"); break; default: console.error("网络异常,请稍后重试"); } return Promise.reject(error); } ); export default service; ``` 2. 创建请求`src/api/user/index.js` ```js import request from "@/utils/request"; // 示例:获取用户信息 export const getUserInfo = () => { return request({ url: '/user/getUserInfo', method: 'get', }); }; ``` ------ ### 十、外部字体引入 ```css /* * src/assets/fonts/font.css * ttf字体文件放在同级目录下 './' * * font-family - 自定义字体名称 * src - 字体路径 * font-weight - 字体粗细 * font-style - 字体样式 */ /* 字体引入 */ @font-face { font-family: 'Typeface'; src: url('./typeface.ttf') format('truetype'); font-weight: normal; font-style: normal; } ``` ------ ### 十一、项目指令 ```bash # 运行项目 npm run dev # 打包项目 npm run build ```
Welcome, {{ username }} (Token: {{ token }})