Axios와 Ajax를 구별하는 데 주의해야 합니다.
Ajax는 기술에 대한 일반적인 용어입니다. 기술 콘텐츠에는 HTML 또는 XHTML, CSS, JavaScript, DOM, XML, XSLT 및 가장 중요한 XMLHttpRequest는 브라우저와 서버 간의 비동기 데이터 전송(HTTP 요청)을 사용하여 로컬 새로 고침을 달성하기 위해 로컬 요청을 수행합니다.
Axios는 약속 기반 HTTP 라이브러리이며 타사입니다. library
주요 기술 스택: vue3, ts, axios, mock.js, elementPlus
// 安装axios npm install axios --save // 安装 elementPlus npm install element-plus --save
2. Global axios 패키지
src 디렉토리 아래에 새로운 request.ts를 생성합니다. TS를 사용하기 때문에 데이터 형식을 미리 정의해야 합니다. :src 디렉터리를 사용하여 api/index.ts요청 데이터 반환 정의 형식을 미리 확인해야 합니다
3. 실제로- Axios 기본 구성 정보 정의
- 요청 인터셉터: 모든 요청이 먼저 도착하는 경우 여기에서 요청 헤더 정보를 맞춤 설정할 수 있습니다(예: 토큰, 다국어 등 )
- 응답 인터셉터: 데이터가 처음 도착하는 장소를 반환합니다. 여기서 예외 정보를 처리할 수 있습니다(예: 코드 401은 로그인으로 리디렉션되고, 코드 500은 오류 메시지를 표시합니다)
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"; import { ElMessage, ElLoading, ElMessageBox } from "element-plus"; // response interface { code, msg, success } // 不含 data interface Result { code: number, success: boolean, msg: string } // request interface,包含 data interface ResultData<T = any> extends Result { data?: T } enum RequestEnums { TIMEOUT = 10000, // 请求超时 request timeout FAIL = 500, // 服务器异常 server error LOGINTIMEOUT = 401, // 登录超时 login timeout SUCCESS = 200, // 请求成功 request successfully } // axios 基础配置 const config = { // 默认地址,可以使用 process Node内置的,项目根目录下新建 .env.development baseURL: process.env.VUE_APP_BASE_API as string, timeout: RequestEnums.TIMEOUT as number, // 请求超时时间 withCredentials: true, // 跨越的时候允许携带凭证 } class Request { service: AxiosInstance; constructor(config: AxiosRequestConfig) { // 实例化 serice this.service = axios.create(config); /** * 请求拦截器 * request -> { 请求拦截器 } -> server */ this.service.interceptors.request.use( (config: AxiosRequestConfig) => { const token = localStorage.getItem('token') ?? ''; return { ...config, headers: { 'customToken': "customBearer " + token } } }, (error: AxiosError) => { // 请求报错 Promise.reject(error) } ); /** * 响应拦截器 * response -> { 响应拦截器 } -> client */ this.service.interceptors.response.use( (response: AxiosResponse) => { const { data, config } = response; if (data.code === RequestEnums.LOGINTIMEOUT) { // 表示登录过期,需要重定向至登录页面 ElMessageBox.alert("Session expired", "System info", { confirmButtonText: 'Relogin', type: 'warning' }).then(() => { // 或者调用 logout 方法去处理 localStorage.setItem('token', ''); location.href = '/' }) } if (data.code && data.code !== RequestEnums.SUCCESS) { ElMessage.error(data); return Promise.reject(data); } return data }, (error: AxiosError) => { const { response } = error; if (response) { this.handleCode(response.status); } if (!window.navigator.onLine) { ElMessage.error("网络连接失败,请检查网络"); // 可以重定向至404页面 } } ) } public handleCode = (code: number): void => { switch (code) { case 401: ElMessage.error("登陆失败,请重新登录"); break; case 500: ElMessage.error("请求异常,请联系管理员"); break; default: ElMessage.error('请求失败'); break; } } // 通用方法封装 get<T>(url: string, params?: object): Promise<ResultData<T>> { return this.service.get(url, { params }); } post<T>(url: string, params?: object): Promise<ResultData<T>> { return this.service.post(url, params); } put<T>(url: string, params?: object): Promise<ResultData<T>> { return this.service.put(url, params); } delete<T>(url: string, params?: object): Promise<ResultData<T>> { return this.service.delete(url, { params }); } } export default new Request(config)로그인 후 복사
요청의 매개변수 유형을 정의합니다.
여기서 사용합니다. 실제 개발을 위한 TS의 네임스페이스 많은 API가 동일한 이름과 다른 의미를 가질 수 있으므로 네임스페이스를 사용하여- 응답의 특정 매개변수 유형을 정의합니다
Vue 파일에서 호출import request from "@/utils/request"; namespace User { // login export interface LoginForm { userName: string, password: string } } export namespace System { export interface Info { path: string, routeName: string } export interface ResponseItem { code: number, items: Array<Sidebar>, success: boolean } export interface Sidebar { id: number, hashId: string | number, title: string, routeName: string, children: Array<SidebarItem>, } export interface SidebarItem { id: number, parentId: number, hashId: string | number, title: string, } } export const info = (params: System.Info) => { // response if (!params || !params.path) throw new Error('Params and params in path can not empty!') // 这里因为是全局的一个info,根据路由地址去请求侧边栏,所需不用把地址写死 return request.post<System.Sidebar>(params.path, { routeName: params.routeName }) }로그인 후 복사
<script lang="ts" setup name="Sidebar"> import { ref, reactive, onBeforeMount } from "vue" import { info } from "@/api" import { useRoute } from "vue-router" const route = useRoute(); let loading = ref<boolean>(false); let sidebar = ref<any>({}); const _fetch = async (): Promise<void> => { const routeName = route.name as string; const path = '/' + routeName.replace(routeName[0], routeName[0].toLocaleLowerCase()) + 'Info' try { loading.value = true; const res = await info({ path, routeName }); if (!res || !res.data) return; sidebar.value = res.data; } finally { loading.value = false } } onBeforeMount(() => { _fetch(); }) </script>
을 정의합니다. 2. mock.js의 종속성 설치 및 처리
# 安装 npm install mockjs --save
/* eslint-disable */ declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component } declare module 'mockjs';
2. new mock
index.ts(mockjs 전역 구성 파일에 속함), mockjs/javaScript/index.ts(특정 데이터 파일), 이 두 가지에 주의해야 하며 다른 것에는 주의할 필요가 없습니다
1. 새로운 mockjs/javaScript/index.ts(특정 데이터 파일)을 생성하세요
여기 데이터는 주로 사이드바 데이터이기 때문에 모두 고정되어 있으므로 데이터 생성에 mockjs 규칙을 사용하지 않습니다
import { GlobalSidebar, Sidebar } from "../../sidebar";
namespace InfoSidebar {
export type InfoSidebarParams = {
body: string,
type: string,
url: string
}
}
const dataSource: Array<GlobalSidebar> = [
{
mainTitle: 'JavaScript基础问题梳理',
mainSidebar: [
{
id: 0,
hashId: 'This',
title: 'this指向',
routeName: 'JsBasic',
children: [
{
id: 1,
parentId: 0,
hashId: 'GlobalFunction',
title: '全局函数'
},
{
id: 2,
parentId: 0,
hashId: 'ObjectMethod',
title: '对象方法'
},
{
id: 3,
parentId: 0,
hashId: 'Constructor',
title: '构造函数'
},
{
id: 4,
parentId: 0,
hashId: 'SetTimeout',
title: '定时器、回调函数'
},
{
id: 5,
parentId: 0,
hashId: 'EventFunction',
title: '事件函数'
},
{
id: 6,
parentId: 0,
hashId: 'ArrowFunction',
title: '箭头函数'
},
{
id: 7,
parentId: 0,
hashId: 'CallApplyBind',
title: 'call、apply、bind'
},
]
},
{
id: 2,
hashId: 'DeepClone',
title: '深拷贝和浅拷贝',
routeName: 'JsBasic',
children: []
}
]
},
];
export default {
name: 'jsBasicInfo',
jsBasicInfo(params: InfoSidebar.InfoSidebarParams) {
const param = JSON.parse(params.body)
if (!param) throw new Error("Params can not empty!");
const data = dataSource.find((t: GlobalSidebar) => {
return t.mainSidebar.filter((x: Sidebar) => {
return x.routeName === param.routeName
})
})
return {
data,
success: true,
code: 200
}
}
}
/** * @param { number } id Unique value * @param { string } hashId href Unique value * @param { string } title show current title * @param { string } routeName page find data */ interface GlobalSidebar { mainTitle: string, mainSidebar: Array<Sidebar> } interface Sidebar { id: number, hashId: string | number, title: string, routeName: string, children: Array<SidebarItem>, } interface SidebarItem { id: number, parentId: number, hashId: string | number, title: string, } export { GlobalSidebar, Sidebar, SidebarItem }
2. 새로운 mockjs/index.ts 생성
import Mock from "mockjs"; import jsBasicInfo from "./tpl/javaScript/index"; const requestMethod = 'post'; const BASE_URL = process.env.VUE_APP_BASE_API; const mocks = [jsBasicInfo]; for (let i of mocks) { Mock.mock(BASE_URL + '/' + i.name, requestMethod, i.jsBasicInfo); } export default Mock
3. Main.ts는
import { createApp } from 'vue' import App from './App.vue' if(process.env.NODE_ENV == 'development'){ require('./mockjs/index') } const app = createApp(App); app.mount('#app');
3을 소개합니다. 사실은 방금 axios
<script lang="ts" setup name="Sidebar"> import { ref, reactive, onBeforeMount } from "vue" import { info } from "@/api" import { useRoute } from "vue-router" const route = useRoute(); let loading = ref<boolean>(false); let sidebar = ref<any>({}); const _fetch = async (): Promise<void> => { const routeName = route.name as string; const path = '/' + routeName.replace(routeName[0], routeName[0].toLocaleLowerCase()) + 'Info' try { loading.value = true; const res = await info({ path, routeName }); if (!res || !res.data) return; sidebar.value = res.data; } finally { loading.value = false } } onBeforeMount(() => { _fetch(); }) </script>
위 내용은 axios를 캡슐화하고 vue3 및 ts와 함께 mock.js를 사용하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!