一、任务目标:掌握Form表单的验证、使用axios调用后端接口、解决前后端跨域问题
二、实验步骤
1、使用Postman验证后端接口
(1)登录接口:http://127.0.0.1:8000/login/
(2)注册接口:http://127.0.0.1:8000/register/
2、安装
npm install axios --save
3、配置vite.config.ts,在此配置文件中增加server配置,解决前后端跨域问题
server: {
port: 8080,
host: "0.0.0.0",
// 反向代理
proxy: {
"/api": {
target: "http://127.0.0.1:8000/",// 本地调试
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
7、新建utils/request.ts
import axios from 'axios';
import { errorCodeType } from '../utils/error-code-type';
import { ElMessage, ElLoading } from 'element-plus';
import { AxiosRequestConfig, AxiosResponse } from "axios";
// 创建axios实例
const service = axios.create({
// 服务接口请求
// baseURL: "import.meta.env.VITE_APP_BASE_API",
baseURL: "/",
// 超时设置
timeout: 15000,
headers: { 'Content-Type': 'application/json;charset=utf-8' }
})
let loading: any;
//正在请求的数量
let requestCount: number = 0
//显示loading
const showLoading = () => {
if (requestCount === 0 && !loading) {
loading = ElLoading.service({
text: "拼命加载中,请稍后...",
background: 'rgba(0, 0, 0, 0.7)',
spinner: 'el-icon-loading',
})
}
requestCount++;
}
//隐藏loading
const hideLoading = () => {
requestCount--
if (requestCount == 0) {
loading.close()
}
}
// 请求拦截
service.interceptors.request.use(config => {
showLoading()
// 是否需要设置 token
// config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use((res: any) => {
hideLoading()
// 未设置状态码则默认成功状态
const code = res.data['code'] || 200;
// 获取错误信息
const msg = errorCodeType(code) || res.data['msg'] || errorCodeType('default')
if (code === 200) {
return Promise.resolve(res.data)
} else {
ElMessage.error(msg)
return Promise.reject(res.data)
}
},
error => {
console.log('err' + error)
hideLoading()
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
ElMessage.error({
message: message,
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service;
8、新建utils/error-code-type.ts
export const errorCodeType = function(code:string):string{
let msg:string = ""
switch (code) {
case "401":
msg = '认证失败,无法访问系统资源'
break;
case "403":
msg = '当前操作没有权限'
break;
case "404":
msg = '访问资源不存在'
break;
case "default":
msg = '系统未知错误,请反馈给管理员'
break;
default:
return '未知错误,请联系管理员'
}
return msg
}
9、新建utils/api.ts
import { fi } from "element-plus/es/locale";
import request from "../utils/request";
export function register(data: any) {
return request({
url: 'api/register/',
method: 'post',
data: data,
})
}
export function login(data: any) {
return request({
url: 'api/login/',
method: 'post',
data: data,
})
}
10、新建views/login.vue
11、新建views/register.vue