vue + node 管理系统的建站流程(前端篇)
前言
本次练手项目前端技术栈为Vue + element-ui,后端技术栈为node + express,具体目标是实现一个后台管理系统的基本功能,这里主要记录一下具体流程
- 编写登录页
<div class="container">
<div class="form">
<el-form
:model="loginForm"
ref="form"
:rules="rules"
label-width="80px"
:inline="false"
size="normal"
status-icon
>
<h3 class="title">管理員登錄</h3>
<el-form-item label="用戶名:" prop="email" max="12" min="6" autocomplete="off">
<el-input v-model="loginForm.email"></el-input>
</el-form-item>
<el-form-item label="密碼:" prop="password" max="15" min="8" autocomplete="off">
<el-input type="password" v-model="loginForm.password"></el-input>
</el-form-item>
<el-form-item style="width: 100%;">
<el-button class="submit" type="primary" @click="handleSubmit" size="large">登錄</el-button>
</el-form-item>
</el-form>
</div>
</div>
- 编写router.js
import { createRouter, createWebHistory } from 'vue-router'
import { auth } from '@/utlis/auth'
const Login = () => import('@/views/rl/Login.vue')
const errorPage = () => import("@/views/errorPage/404.vue")
const index = () => import('@/views/index.vue')
const Register = () => import('@/views/rl/Register.vue')
const routes = [
{
path: '/index',
name: 'index',
component: index
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/register',
name: 'register',
component: Register
},
{
path: "/404",
name: "notFound",
component: errorPage
},
{
path: '/:catchAll(.*)',
redirect: '/404'
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
//判断是否已经登录,若没有token则只能进入login或register页
router.beforeEach((to,name,next) => {
const isLogin = auth.getAuthorization() ? true : false;
if(to.path === '/login' || to.path === '/register') {
next()
} else {
if(isLogin) {
next();
} else {
next({path: '/login'})
}
}
})
export default router
3.封装request组件,方便后续api调用
import axios from 'axios'
import store from '@/store'
import { ElLoading,ElMessage,ElMessageBox } from 'element-plus'
import router from '@/router/index'
import {auth} from '@/utlis/auth'
// 创建axios实例
const service = axios.create({
baseURL: '/api', // api的base_url
timeout: 5000 // 请求超时时间
})
let loading = null;
//调用api时开启加载动画
function startLoading() {
loading = ElLoading.service({
lock: true,
text: '拼命加载中....',
background: 'rgba(0,0,0,0.7)'
})
}
//关闭加载动画
function endLoading() {
loading.close();
}
// 设置 post、get默认 Content-Type
// service.defaults.headers.post['Content-Type'] = 'application/json'
// service.defaults.headers.get['Content-Type'] = 'application/json'
// request拦截器
service.interceptors.request.use(config => {
//加载动画
startLoading();
// 如果当前已有token,则在请求头中加上
if (auth.getAuthorization()) {
//设置统一的请求头
config.headers['Authorization'] = auth.getAuthorization()// 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
}
return config
}, error => {
// Do something with request error
ElMessage({
message: error,
type: 'error'
})
Promise.reject(error)
})
// respone拦截器
service.interceptors.response.use(
/**
* 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
* 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
*/
response => {
const res = response.data;
if (response.status != 200) {
ElMessage({
message: res.msg,
type: 'error'
});
return Promise.reject('error');
}
//结束加载动画
endLoading();
//弹出消息框,并跳转到主页
ElMessage({
message: '成功登录',
type: 'success'
});
router.push('/index');
return response;
},
error => {
endLoading();
const { status } = error.response;
//根据status码来判断token是否过期,若过期则退出登录并返回登录页
if(status == 401) {
ElMessageBox.confirm('token已经失效请重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//删除存储对象中的Token
store.dispatch('setAuthorization',false).then(()=>{
auth.removeAuthorization();
location.reload();
});
router.push('/login');
})
auth.removeAuthorization();
}
ElMessage({
message: error.response.data.msg,
type: 'error'
})
return Promise.reject(error)
})
//加载到vue实例上,成为全局方法
export default {
install: function(app) {
app.config.globalProperties.$http = service;
}
}
export const request = service
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了