论坛项目
后端管理系统
服务器地址:
http://172.16.11.18:9090
swagger地址:
http://172.16.11.18:9090/doc.html
前端h5地址:
http://172.16.11.18:9099/h5/#/
前端管理系统地址:
http://172.16.11.18:9099/admin/#/
搭建项目
vue create . 创建项目
搭建项目的架构(目录的相关)
分析系统结构
分析系统整个项目分为:
路由结构:一级路由一级二级路由涉及到重定向
根据分析安装路由:
用vue2所以对应使用 vue router@3
配置路由的入口文件初步代码(在router.js文件中):
//vue入口文件,创建路由以及导出路由
import Vue from "vue";
import VueRouter from "vue-router";
//注册
vue.use(VueRouter)
//创建路由实例
const router=new VueRouter({
mode:"hash",
routes:[],
base:'/admin',
//配置滚动的 --用户切换路由组件后回到顶部
scrollBehavior(){
return{x:0,y:0} //返回return 一个对象 回到(0,0)(左上角)坐标
}
})
//暴露文件
export default router
引入使用路由文件(在main.js中)
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
//引入路由文件
import router from "./router";
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
在router文件下创建 routers 放这些路径
配置静态路由文件(在routes.js文件中)
//路由配置
//同步引入 之间
import Admin from "../views/admin.vue"
import Login from "../views/login.vue"
import Error from "../views/error.vue"
export default [
{
path:"/",
component:Admin
},
{
path:"/login",
component:Login
},
{
path:"/error",
component:Error
},
]
在views文件夹下面创建三个组件
在里面写各自的内容(这里以login.vue为举例)
在App.vue中配置一级路由出口
<template>
<div id="app">
<!-- 使用路由的内置组件 -->
<router-view></router-view>
</div>
</template>
测试项目路由是否正常
分析什么情况进error,用户在地址栏输入非路由路径 直接进入404
{
// 非路由直接进error
path: "*",
redirect: "/error",
},
为了项目首次启动加载的问题。如果同步大量引入组件,vue项目首次启动需要加载同步组件进行编译,会造成白屏时间过长,需要降组件转化为异步懒加载方式。
export default [
{
path: "/",
component: () => import("../views/admin.vue"),
//按需组件加载 require() 了解
},
{
path: "/login",
component: () => import("../views/login.vue"),
},
{
path: "/error",
component: () => import("../views/error.vue"),
},
{
// 非路由直接进error
path: "*",
redirect: "/error",
},
];
实现登录流程
使用工具 apipost 测试 接口
测试接口完毕之后,在项目中实现network网络 请求封装
安装axios 请求插件
npm i axios
在utils工具类文件创建request.js 请求文件
实现axios 封装
/**
* 网络请求axios 封装
* **/
import axios from "axios";
//创建方式写法
// const http=axios.create({
// });
//设置axios的配置
//配置请求基本路径
axios.defaults.baseURL = "";
// 配置axios 超时
axios.defaults.timeout = 2000;
//配置请求头
axios.defaults.headers.post["Content-Type"] = "application/json";
//请求拦截器
//config 请求配置
axios.interceptors.request.use(
(config) => {
// 必带返回值
return config;
},
(error) => {
//请求报错
return Promise.reject(error);
}
);
//响应拦截器
axios.interceptors.response.use(
(response) => {
//响应成功
return Promise.resolve(response);
},
(error) => {
return Promise.reject(error);
}
);
//封装get post 请求
export const get = (url, data, type) => {
return axios({
method: "get",
url: url,
params: data,
headers: type,
});
};
export const post = (url, data, type) => {
return axios({
method: "post",
url: url,
data: data,
headers: type,
});
};
axios 二次封装文件完成之后,在network文件中按照模块化整理接口
使用captch 验证码 产生uuid值
封装了一个utils 工具类 产生uid值
/**
* 通用的工具类
* **/
export const getUuid = () => {
//产生uuid值
return "xxxxx-xxxxy-xxyxx-xyxxx".replace(/[xy]/g, (c) => {
return (
c === "x" ? Math.ceil(Math.random() * 16) || 0 : "a" || "b"
).toString(16);
});
};
在login组件中使用uuid值展示验证码图片
<template>
<div>
账号:<input type="text" /> 密码:<input type="text" /> 验证码:<input type="text" />
<img :src="captchUrl" alt="" />
<button>登录</button>
</div>
</template>
<script>
//引入utils
import { getUuid } from "../utils";
export default {
data() {
return {
captchUrl: "http://172.16.11.18:9090/captcha.jpg",
uuid: null,
};
},
created() {
//获取uuid值
this.uuid = getUuid();
this.captchUrl += `?uuid=${this.uuid}`;
},
};
</script>
实现登录
定义登录接口(在network文件下的user.js文件里)
// 用户登录
export const userLogin = (data) => {
return post("/sys/login", data);
};
在登录login组件中执行业务代码
methods: {
async login() {
let { username, password, captcha, uuid } = this;
let res = await userLogin({
uuid,
username,
password,
captcha,
});
console.log(res);
},
},
登录之后实现跳转
封装一个H5缓存类(在utils下的index.js文件中)
//html5 缓存操做
export const findStorage = (key) => {
if (key) return localStorage.getItem(key);
return null;
};
export const setStorage = (key, data) => {
localStorage.setItem(key, JSON.stringify(data));
};
export const removeStorage = (key) => {
localStorage.removeItem(key);
};
登陆之后写入缓存(写在login.vue组件中的methods下)
// 用户登录
async login() {
let { username, password, captcha, uuid } = this;
let res = await userLogin({
uuid,
username,
password,
captcha,
});
console.log(res);
//接入缓存
setStorage("_token", res.data.token);
//编程式路由导航$router
this.$router.replace({ path: "/" });
},
实现系统刷新 检测用户是否登录。
添加守卫做业务处理(那些路由需要处理,那些不需要处理,定义的是项目的白名单,写在router.js里面)
//设置守卫
//定义白名单
const whiteList = ["/login", "/error"];
router.beforeEach((to, from, next) => {
//白名单路由不检测token直接放行
//读取token
let token = findStorage("_token");
//判断token
if (token) {
//用户登录过
//如果进入的是登录界面 直接到系统首页
if (to.path == "/login") {
next({ path: "/" });
}
next();
} else {
//用户未登录
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
next({ path: "/login", query: { redirect: to.path } });
}
}
});
注意;这块需要多思考