做项目时学习到的封装思想

73 阅读2分钟

对于axios网络请求

如果是多个组件,每个组件都需要请求接口数据

  1. 初步想法是直接在每个组件中发送对应网络请求,拿到数据之后再渲染到页面上,但是每一次都要单独引用axios和单独进行数据处理,太繁琐。
axios.get(url).then(res=>{
    console.log(res)
})
  1. 进一步的想法是,对axios进行封装,包括了数据处理的过程,每个组件引用封装过的axios进行网络请求。节省了数据处理的步骤。(此处仅简单封装)
import axios from 'axios'
import { BASE_URL, TIME_OUT } from './config';
class HYRequest {

    constructor(baseURL, timeout = 10000) {
        //返回不一样的实例,可以创建很多个实例
        this.instance = axios.create({
            baseURL,
            timeout
        })
    }

    request(config) {
        // return axios.request(config)
        return new Promise((resolve, reject) => {
            this.instance.request(config).then(res => {
                resolve(res.data)
            }).catch(err => {
                reject(err)
            })
        })
    }

    get(config) {
        return this.request({...config, method: "get" })
    }

    post(config) {
        return this.request({...config, method: "post" })
    }

}

export default new HYRequest(BASE_URL, TIME_OUT)
  1. 再进一步的想法,每个组件在网络请求部分的代码结构高度相似,可以进行抽离封装,在组件中单独使用封装好的方法。但由于各个组件所求数据和接口不同,不能封装到一起,因此在service结构下建立modules文件夹,把各个组件的请求部分封装到单独的js文件中再导出(如下图),可以实现网络请求统一管理,也更方便代码的优化。(request是封装axios的部分),最外层的index是方便外部组件引入,将modules中的方法全部汇总导出。

image.png

//city.js
import HYRequest from '../request'

export function getAllCity() {
    return HYRequest.get({
        url: '/city/all'
    })
}

//最外层的index(有其他组件同理)
export * from './modules/city.js

4.上一步虽然已经进行了分块封装,但是数据都在组件中进行存储了,如果有多个组件,子组件需要数据只能一步一步传递,如果网络请求过多,也会导致组件页面包含大量的网络请求。

优化:将数据管理放到pinia中的store中统一进行,达成页面,数据,网络请求分别在3个地方统一管理。模块化更加明显。网络请求在对应组件store的action中进行,拿到数据之后store对数据进行统一管理,再发送给组件进行数据渲染。

image.png

//store中的city
import { defineStore } from 'pinia';
import { getAllCity } from '@/service'

const useCityStore = defineStore("city", {
    state: () => ({
        allCities: {}
    }),
    actions: {
        async fetchAllCitiesAction() {
            const res = await getAllCity()
            this.allCities = res.data
        }
    }
})

export default useCityStore