从零开始使用vue2+element搭建后台管理系统(前期准备+登录)
准备开始
1. 安装node (node -v查询版本号) (下载地址:https://nodejs.org/en/download/)
2. 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org
3. 安装 webpack,以全局的方式安装
npm install webpack -g
4.全局安装vue以及脚手架vue-cli
npm install @vue/cli -g --unsafe-perm
5.创建vue项目
vue create 项目名称
项目前置配置
- 选择预设模板:Manually select features:手动配置
- 选择需要使用的特性:Babel,Router,Vuex,CSS Pre-processors,Linter / Formatter(单元、E2E测试不选,ts根据项目情况选)
- Router 选择路由模式:选用history(URL 中不带有 # 符号,但需要后台配置支持)
- 选择 CSS Pre-processors:Sass(因为element使用Sass)
- 选择 Linter / Formatter(Pick a linter / formatter config: (Use arrow keys):这里我试着选了ESLint + Prettier,通常选择ESLint + Standard config
- 选择在什么时间进行检测(Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)):
- Lint on save:保存时检测(√)
- Lint and fix on commit:提交时检测
- 选择在什么位置保存配置文件(Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys)):In dedicated config files
- 选择是否保存本次配置以便于下次使用(Save this as a preset for future projects? (y/N)):N
配置好后,会自动生成一个项目,根据终端的提示,cd进入项目后,执行npm run serve,本地环境的运行命令可以自己配
导入element
官方文档:https://element.eleme.cn/#/zh-CN/component/installation
全局导入命令:npm i element-ui -S
在main.js中引入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import Vue from "vue" ; import App from "./App.vue" ; import router from "./router" ; import store from "./store" ; import 'element-ui/lib/theme-chalk/index.css' import ElementUI from 'element-ui' Vue.use(ElementUI) Vue.config.productionTip = false ; new Vue({ router, store, render: (h) => h(App), }).$mount( "#app" ); |
创建路由 (router/index.js)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | import Vue from "vue" ; import VueRouter from "vue-router" ; Vue.use(VueRouter); import LoginView from "../views/LoginView.vue" ; import HomeView from "../views/HomeView.vue" ; import LayoutView from "@/components/LayoutView" ; /** 解决相同路径跳转报错 */ const originalPush = VueRouter.prototype.push; VueRouter.prototype.push = function push(location) { return originalPush.call( this , location). catch ((err) => err); }; export const constantRoutes = [ // 重定向 { path: "/" , redirect: "/home" , // 重定向到首页 component: LayoutView, children: [ { path: "home" , name: "home" , component: HomeView, meta: { title: "home" , icon: "home" }, }, ], }, //login { path: "/login" , component: LoginView, }, // 重定向 { path: "/home" , redirect: "/home" , component: LayoutView, children: [ { path: "home" , name: "home" , component: HomeView, meta: { title: "home" , icon: "home" }, }, ], }, { path: "/user" , component: LayoutView, redirect: "/user/user" , children: [ { path: "user" , name: "user" , component: () => import ( "@/views/user/index" ), meta: { title: "账号管理" , icon: "s-custom" }, }, ], }, { path: "/order" , component: LayoutView, redirect: "/order/order" , children: [ { path: "order" , name: "order" , component: () => import ( "@/views/order/index" ), meta: { title: "订单管理" , icon: "s-marketing" }, }, ], }, { path: "/auth" , component: LayoutView, redirect: "/auth/auth" , children: [ { path: "auth" , name: "auth" , component: () => import ( "@/views/auth/index" ), meta: { title: "权限管理" , icon: "s-tools" }, }, ], }, { path: "/404" , component: () => import ( "@/views/404" ), hidden: true , }, ]; const createRouter = () => new VueRouter({ mode: "history" , base: process.env.BASE_URL, scrollBehavior: () => ({ y: 0, // scrollBehavior用于定义路由切换时,页面滚动 }), routes: constantRoutes, }); const router = createRouter(); export default router; |
引入axios
官网::http://www.axios-js.com/ (基于Promise的HTTP客户端,用于发送HTTP请求)
安装:npm install axios -S
创建一个名为utils的文件夹,在其中创建一个名为request.js的文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | // 封装请求函数 import axios from "axios" ; // 路由守卫 import router from "../router" ; import { getToken, removeToken } from "./auth.js" ; import { Message } from "element-ui" ; // 创建axios实例 const service = axios.create({ // 通用请求的地址前缀 // baseURL: '/api', baseURL: process.env.BASE_API, timeout: 5000, // 请求带上 cookie withCredentials: true , // 定义消息头 headers: { "Content-Type" : "application/json; charset=utf-8" , }, }); // 请求拦截器 service.interceptors.request.use( (config) => { // // 在请求头中携带token // config.headers.Authorization = localStorage.getItem("token"); config.headers[ "Admin-Token" ] = getToken(); return config; }, (error) => { console.log(error); Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( (response) => { const res = response.data; // 请求成功,返回数据 if (res.code === 200) { return res; } else { // 根据状态码提示错误信息 switch (res.code) { case 401: // 无权限,跳转到登录页面并清除token // localStorage.removeItem("token"); removeToken(); Message({ message: res.message, type: "error" , duration: 5000, }); router.push( "/login" ); break ; case 403: alert( "没有操作权限" ); break ; case 404: alert( "请求的资源不存在" ); // todo: 这里可以跳转到404页面 break ; case 500: alert( "服务器内部错误" ); break ; default : alert(res.message); } return Promise.reject(res.message || "Error" ); } }, (error) => { console.log( "err" + error); return Promise.reject(error); } ); export default service; |
引入js-cookie用来管理cookie
npm install js-cookies -S
继续在utils文件夹下创建一个创建一个名为auth.js的文件,用来管理token:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const TokenKey = "Admin-Token" ; import Cookie from "js-cookies" ; // get export function getToken() { return Cookie.getItem(TokenKey); } // set cookie有效期设置为客服交班时间14小时 export function setToken(value) { let seconds = 14 * 60 * 60; let expires = new Date( new Date() * 1 + seconds * 1000); console.log(TokenKey, value, expires); return Cookie.setItem(TokenKey, value, expires); } // remove export function removeToken() { return Cookie.removeItem(TokenKey); } |
这里提供的方法就可以在需要的地方使用了~
最后src/main.js文件的内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import Vue from "vue" ; import App from "./App.vue" ; import router from "./router" ; import store from "./store" ; import "element-ui/lib/theme-chalk/index.css" ; import ElementUI from "element-ui" ; import Cookie from "js-cookies" ; import request from "./utils/request" ; import api from "./api" ; // 导入api接口 //导入permission.js,用户进行前端的权限控制 // import "./permission" // 路由守卫 router.beforeEach((to, from, next) => { // 判断是否需要登录才能访问该路由 // if (to.meta.requireAuth) { // 判断是否存在token const token = Cookie.getItem( "Admin-Token" ); if (!token && to.path !== "/login" ) { next({ path: "/login" , query: { redirect: to.fullPath }, }); } else if (token && to.path === "/login" ) { next({ name: "home" }); } else { next(); } }); Vue.use(ElementUI); Vue.config.productionTip = false ; Vue.prototype.$http = request; Vue.prototype.$api = api; // 将api挂载到vue的原型上 new Vue({ router, store, render: (h) => h(App), }).$mount( "#app" ); |
在views文件夹下创建LoginView.vue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | <template> <div class = "sign-in" > <el-row> <el-col :span= "12" :offset= "6" > <img class = "login-logo" src= "../assets/logo.png" alt= "烛月后台管理系统" /> <el-form :model= "loginForm" :rules= "loginRules" ref= "ruleForm" class = "login-form" auto-complete= "on" label-position= "left" > <el-form-item prop= "name" > <el-input ref= "username" v-model= "loginForm.name" placeholder= "Username" name= "username" type= "text" tabindex= "1" auto-complete= "on" /> </el-form-item> <el-form-item prop= "password" > <el-input key= "password" ref= "password" v-model= "loginForm.password" type= "password" placeholder= "Password" name= "password" tabindex= "2" auto-complete= "on" /> </el-form-item> <el-form-item> <el-button :loading= "loading" type= "primary" style= "width: 100%; margin-bottom: 16px" @click= "handleLogin('ruleForm')" >登录</el-button > <el-button style= "width: 100%; margin-left: 0" @click= "resetForm('ruleForm')" >重置</el-button > </el-form-item> </el-form> </el-col> </el-row> </div> </template> <script> import { login } from "../api/user" ; import { setToken } from "@/utils/auth" ; export default { data() { return { loading: false , loginForm: { name: "" , password: "" , }, loginRules: { name: [{ required: true , message: "请输入用户名" , trigger: "blur" }], password: [{ required: true , message: "请输入密码" , trigger: "blur" }], }, }; }, methods: { async handleLogin(formName) { this .$refs[formName].validate(async (valid) => { if (valid) { try { this .loading = true ; const params = { data: { mobile: this .loginForm?.name, password: this .loginForm?.password, }, }; const res = await login(params); if (res.code !== 10000) this .$message.error(res.msg || "登录失败!" ); if (res.code === 10000 && res.data?.token) { this .$store.commit( "user/SET_TOKEN" , res.data.token); setToken(res.data.token); setTimeout(() => { this .$router.push({ name: "/home" , }); }); } } finally { this .loading = false ; } } else { this .$message.error( "输入有误!" ); } }); }, resetForm(formName) { this .$refs[formName].resetFields(); }, }, }; </script> <style scoped lang= "scss" > .sign- in { padding-top: 100px; } .login-logo { height: 100px; } .login-form { position: relative; width: 520px; max-width: 100%; padding: 30px 35px 0; margin: 0 auto; overflow: hidden; } </style> |
登录成功后,进行token的存储,同时跳转到主页。
在api文件夹下新建user.js文件,写几个假的登录相关接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * 登录模块接口列表 */ import request from "../utils/request" ; // 导入http中创建的axios实例 // import qs from "qs"; // 根据需求是否导入qs模块 export function login(params) { console.log(params, "params" ); return { code: 10000, msg: "登录成功" , data: { token: "abcdefghijklmnopqrstuvwxyz0123456789" , }, }; // return request.post("api/user/login", qs.stringify(params)); } export function getInfo() { return { url: "api/user/info" , type: "post" , data: { msg: "success" , code: 0, }, }; } export function logout() { return request({ url: "api/user/logout" , method: "post" , }); } |
运行效果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具