
Vue 快速开发模板 - 项目说明书一、环境准备1.1 安装 nvmNode.js 版本管理工具nvm 用于管理多个 Node.js 版本方便切换。下载地址https://github.com/coreybutler/nvm-windows/releases 下载 nvm-setup.exe 安装即可1.2 使用 nvm 安装 Node.js# 查看可安装的版本 nvm list available 安装 Node.js 22.x LTS 版本 nvm install 22 切换到 22.x 版本 nvm use 22.x.x具体版本号 验证安装 node -v # 应显示 v22.x.x npm -v # 应显示 10.x.x1.3 常见问题nvm use 后 node -v 还是旧版本原因PATH 环境变量中有写死的旧版本路径。解决方法 1. 右键此电脑 → 属性 → 高级系统设置 → 环境变量 2. 在 Path 中找到类似 D:\xxx\nvm\nvm\v14.21.3\ 的路径 3. 删除这一行 4. 确认 NVM_HOME 和 NVM_SYMLINK 环境变量存在 5. 关闭所有命令行窗口重新打开 6. 执行 nvm use 22.x.x再执行 node -v 验证1.4 常见问题npm 命令报安全策略错误错误信息无法加载文件 npm.ps1因为在此系统上禁止运行脚本。解决方法以管理员身份运行 PowerShell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 输入 Y 回车确认1.5 设置 npm 镜像国内加速npm config set registry https://registry.npmmirror.com1.6 安装 yarnnpm install -g yarn二、创建 Vue 项目2.1 安装 Vue 脚手架yarn global add vue/cli vue --version # 应显示 vue/cli 5.x.x2.2 创建项目# 切换到你想放项目的目录 cd D:\你的目录 创建项目 vue create quick-dev-template2.3 创建时的选项配置第1步选择 Manually select features手动选择功能 第2步勾选以下功能空格键选中回车确认 ✅ Babel ✅ Router ✅ Vuex ✅ CSS Pre-processors ✅ Linter / Formatter 第3步Vue 版本选择 3.x 第4步Use history mode for router? → Yes 第5步CSS 预处理器 → Sass/SCSS (with dart-sass) 第6步ESLint → ESLint Prettier 第7步Lint on save保存时检查 第8步配置文件位置 → In dedicated config files 第9步Save as preset? → No 第10步包管理器 → Use Yarn三、安装依赖cd quick-dev-template 安装 Element PlusUI 组件库 yarn add element-plus 安装 axiosHTTP 请求库 yarn add axios 安装 js-cookieCookie 管理库 yarn add js-cookie四、项目配置4.1 入口文件 src/main.jsimport { createApp } from vue; import App from ./App.vue; import router from ./router; import store from ./store; // Element Plus import ElementPlus from element-plus; import element-plus/dist/index.css; import zhCn from element-plus/dist/locale/zh-cn.mjs; const app createApp(App); app.use(store); app.use(router); app.use(ElementPlus, { locale: zhCn }); app.mount(#app);4.2 路由配置 src/router/index.jsimport { createRouter, createWebHashHistory } from vue-router; import Cookies from js-cookie; const routes [ { path: /login, name: Login, component: () import(/views/login/index.vue), }, { path: /, name: Layout, component: () import(/views/layout/index.vue), redirect: /home, children: [ { path: home, name: Home, component: () import(/views/home/index.vue), }, { path: center, name: Center, component: () import(/views/center/index.vue), }, // ↓↓↓ 以后新增的页面路由写在这里 ↓↓↓ ], }, { path: /:pathMatch(.), name: NotFound, component: () import(/views/404/index.vue), }, ]; const router createRouter({ history: createWebHashHistory(), routes, }); // 路由守卫每次跳转前检查是否登录 router.beforeEach((to, from, next) { const token Cookies.get(token); if (to.path /login) { next(); } else if (!token) { next(/login); } else { next(); } }); export default router;4.3 状态管理 src/store/index.jsimport { createStore } from vuex; import Cookies from js-cookie; export default createStore({ state: { user: {}, token: Cookies.get(token) || , }, getters: { getUser(state) { return state.user; }, getToken(state) { return state.token; }, }, mutations: { setUser(state, user) { state.user user; }, setToken(state, token) { state.token token; Cookies.set(token, token); }, logout(state) { state.user {}; state.token ; Cookies.remove(token); }, }, actions: {}, modules: {}, });4.4 HTTP 请求工具 src/utils/request.jsimport axios from axios; import { ElMessage } from element-plus; import router from /router; import Cookies from js-cookie; const service axios.create({ baseURL: http://localhost:8080/springboot, // 后端接口地址根据实际情况修改 timeout: 30000, }); // 请求拦截器自动带上 token service.interceptors.request.use( (config) { const token Cookies.get(token); if (token) { config.headers[Token] token; } return config; }, (error) { return Promise.reject(error); } ); // 响应拦截器统一处理错误 service.interceptors.response.use( (response) { const res response.data; if (res.code 401) { ElMessage.error(请先登录); router.push(/login); return Promise.reject(new Error(未登录)); } return res; }, (error) { ElMessage.error(error.message || 请求失败); return Promise.reject(error); } ); export default service;4.5 根组件 src/App.vuetemplate router-view / /template style langscss { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, 微软雅黑, Arial, sans-serif; } /style4.6 ESLint 配置 .eslintrc.jsmodule.exports { root: true, env: { node: true, }, extends: [plugin:vue/vue3-essential, eslint:recommended], parserOptions: { parser: babel/eslint-parser, }, rules: { no-console: process.env.NODE_ENV production ? warn : off, no-debugger: process.env.NODE_ENV production ? warn : off, vue/multi-word-component-names: off, no-unused-vars: off, }, };五、基础页面5.1 登录页 src/views/login/index.vuetemplate div classlogin-container div classlogin-box h2 classlogin-title系统登录/h2 el-form :modelloginForm :rulesrules refloginFormRef el-form-item propusername el-input v-modelloginForm.username placeholder请输入账号 prefix-iconUser / /el-form-item el-form-item proppassword el-input v-modelloginForm.password typepassword placeholder请输入密码 prefix-iconLock show-password / /el-form-item el-form-item el-radio-group v-modelloginForm.role el-radio labeladmin管理员/el-radio el-radio labeluser普通用户/el-radio /el-radio-group /el-form-item el-form-item el-button typeprimary stylewidth: 100% clickhandleLogin登 录/el-button /el-form-item /el-form /div /div /template script import Cookies from js-cookie; export default { name: Login, data() { return { loginForm: { username: , password: , role: admin, }, rules: { username: [{ required: true, message: 请输入账号, trigger: blur }], password: [{ required: true, message: 请输入密码, trigger: blur }], }, }; }, methods: { handleLogin() { this.$refs.loginFormRef.validate((valid) { if (!valid) return; // TODO: 替换为实际的登录接口 Cookies.set(token, test-token); this.$store.commit(setToken, test-token); this.$store.commit(setUser, { username: this.loginForm.username }); this.$message.success(登录成功); this.$router.push(/); }); }, }, }; /script style langscss scoped .login-container { width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } .login-box { width: 400px; padding: 40px; background: #fff; border-radius: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); } .login-title { text-align: center; margin-bottom: 30px; color: #333; font-size: 24px; } /style5.2 主框架 src/views/layout/index.vuetemplate div classlayout div classheader div classlogo管理系统模板/div div classuser-info el-dropdown commandhandleCommand span classel-dropdown-link {{ $store.state.user.username || 管理员 }} el-iconarrow-down //el-icon /span template #dropdown el-dropdown-menu el-dropdown-item commandcenter个人中心/el-dropdown-item el-dropdown-item commandlogout divided退出登录/el-dropdown-item /el-dropdown-menu /template /el-dropdown /div /div div classcontainer div classsidebar el-menu :default-activeactiveMenu router el-menu-item index/home el-iconhome-filled //el-icon span首页/span /el-menu-item el-menu-item index/center el-iconuser //el-icon span个人中心/span /el-menu-item !-- ↓↓↓ 以后新增的菜单写在这里 ↓↓↓ -- /el-menu /div div classmain-content router-view / /div /div /div /template script import Cookies from js-cookie; export default { name: Layout, computed: { activeMenu() { return this.$route.path; }, }, methods: { handleCommand(command) { if (command center) { this.$router.push(/center); } else if (command logout) { this.$store.commit(logout); Cookies.remove(token); this.$router.push(/login); this.$message.success(已退出登录); } }, }, }; /script style langscss scoped .layout { height: 100vh; display: flex; flex-direction: column; } .header { height: 60px; background: #409eff; color: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; } .logo { font-size: 20px; font-weight: bold; } .user-info { cursor: pointer; } .el-dropdown-link { color: #fff; display: flex; align-items: center; } .container { flex: 1; display: flex; overflow: hidden; } .sidebar { width: 200px; background: #fff; border-right: 1px solid #e6e6e6; overflow-y: auto; } .main-content { flex: 1; padding: 20px; background: #f5f5f5; overflow-y: auto; } /style5.3 首页 src/views/home/index.vuetemplate div classhome h1欢迎使用管理系统/h1 p这是首页你可以在这里放统计信息、图表等/p /div l