封装持久化:

 1. 定义一个专门持久化读写user模块的类

// 持久化存储
export class UserSetting {

}

// 暴露实例
export const userSetting = new UserSetting()

  2. 使用PersistentStorage持久化,在类中定义initSetting方法统一管理

import { TOKEN_KEY, USER_INFO } from '../constants' // key常量
import { UserInfoClass } from '../viewmodels'

// 持久化存储
export class UserSetting {
  // 持久化存储
  initSetting() {
    PersistentStorage.persistProp<UserInfoClass>(USER_INFO, {}) // 用户信息
    PersistentStorage.persistProp<string>(TOKEN_KEY, '') // token
    // ... 有就在加
  }
}

  3. 使用AppStorage.get获取数据,在类中分别定义get方法

import { TOKEN_KEY, USER_INFO } from '../constants' // key常量
import { UserInfoClass } from '../viewmodels'

// 持久化存储
export class UserSetting {
  // 获取用户信息
  getUser(): UserInfoClass {
    return AppStorage.get<UserInfoClass>(USER_INFO) as UserInfoClass
  }
  // 获取token
  getToken(): string {
    return AppStorage.get<string>(TOKEN_KEY) as string
  }
}

  4. 使用AppStorage.set存储数据,在类中分别定义set方法 

import { TOKEN_KEY, USER_INFO } from '../constants' // key常量
import { UserInfoClass } from '../viewmodels'

// 持久化存储
export class UserSetting {
  // 设置存储
  setUser(user: UserInfoClass) {
    AppStorage.set<UserInfoClass>(USER_INFO, user)
  }
  // 设置token
  setToken(token: string) {
    AppStorage.set<string>(TOKEN_KEY, token)
  }
}

  5. 整体代码:

import { TOKEN_KEY, USER_INFO } from '../constants'
import { UserInfoClass } from '../viewmodels'

// 封装存储
export class UserSetting {
  // 持久化存储
  initSetting() {
    PersistentStorage.persistProp<UserInfoClass>(USER_INFO, {}) // 用户信息
    PersistentStorage.persistProp<string>(TOKEN_KEY, '') // token
    // ... 有就在加
  }

  // 用户信息 -------------------------------------
  // 获取
  getSetting(): UserInfoClass{
    return AppStorage.get<UserInfoClass>(USER_INFO) as UserInfoClass
  }
  // 设置
  setSetting(user: UserInfoClass) {
    AppStorage.set<UserInfoClass>(USER_INFO, user)
  }
  // token --------------------------------------
  // 获取token
  getToken(): string {
    return AppStorage.get<string>(TOKEN_KEY) as string
  }
  // 设置token
  setToken(token: string) {
    AppStorage.set<string>(TOKEN_KEY, token)
  }
  // ------ 有就在加
}
// 导出
export const userSetting = new UserSetting()

注意:要在使用AppStorage之前,UI实例初始化成功后,调用PersistentStorage进行初始化,这样才能将AppStorage中key对应的属性持久化到文件中,我是直接在加载页面的回调中调用的。

 封装axios:

  1. 要先安装啊

        ohpm install @ohos/axios

   2. 创建axios实例

       如果一个项目向多台服务器发送请求,我们就可以用create创建多个实例配置多个服务器的基地址,这就是为甚用create,方便咱们的项目延展

// 创建axios实例
const instance = axios.create({
  baseURL: BASE_URL, // 基地址
  timeout: 10000 // 超时时间
})

   3. 配置请求拦截器

// 请求拦截器
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  const token = userSetting.getToken() // 用刚刚封装的工具获取token
  if (token) {
    // 请求头添加token
    config.headers.Authorization = token
  }
  return config // 返回配置
}, (error: AxiosError) => {
  promptAction.showToast({ message: error.message })
  return Promise.reject(error)
})

   4. 配置响应拦截器

        在这个项目中,只有当后台返回的状态码为200时,才是真正的成功,其他情况就抛出错误,状态码为401则是token超时,404则是地址错误,具体情况要看自家后端。

// 响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {
  // 判断业务状态码
  if (response.data && response.data.code === 200) {
    return response.data.data
  }
  promptAction.showToast({ message: response.data.msg }) // 弹出错误消息
  return Promise.reject(new Error(response.data.msg))

}, (error: AxiosError) => {
  // 响应失败
  if (error.response?.status === 401) {
    promptAction.showToast({ message: '请登录' })
    // 删除token
    userSetting.setToken('') // 删除token
    // 跳转到登录页
    router.replaceUrl({
      url: 'pages/Login/Login'
    })
    // 返回失败
    return Promise.reject(new Error("登录失败"))
  } else if (error.response?.status === 404) {
    promptAction.showToast({ message: '请求地址错误' })
    return Promise.reject(new Error("请求地址错误"))
  }
  promptAction.showToast({ message: error.message })
  return Promise.reject(error)
})

   5. 在封装一层方便咱们用

// 封装axios
class Http {
  // 万能请求 -> 针对于复杂的场景,比如又传params又传data的。因为在响应拦截器中扒了两层data,
  // 所以类型就不用再用AxiosResponse<后台返回数据<具体数据>>包了,直接写传过来的类型即可
  request<ResponseData, Data = Object>(config: AxiosRequestConfig<Data>) {
    return instance.request<null, ResponseData, Data>(config)
  }
  // 封装get请求
  get<ResponseData, Data = undefined>(url: string, params?: Data): Promise<ResponseData> {
    return this.request<ResponseData>({
      url,
      method: 'GET',
      params
    })
  }
  // 封装post请求
  post<ResponseData, Data = undefined>(url: string, data?: Data): Promise<ResponseData> {
    return this.request<ResponseData, Data>({
      url,
      method: 'POST',
      data
    })
  }
  // 封装delete请求
  delete<ResponseData, Data = undefined>(url: string, params?: Data): Promise<ResponseData> {
    return this.request<ResponseData>({
      url,
      method: 'DELETE',
      params
    })
  }
  // 封装put请求
  put<ResponseData, Data = undefined>(url: string, data?: Data): Promise<ResponseData> {
    return this.request<ResponseData, Data>({
      url,
      method: 'PUT',
      data
    })
  }
}

// 导出封装类
export const myHttp = new Http()

   6.整体代码:

import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from '@ohos/axios'
import { userSetting } from '.'
import { BASE_URL } from '../constants'
import { promptAction, router } from '@kit.ArkUI'

// 创建axios实例
const instance = axios.create({
  baseURL: BASE_URL, // 设置基础地址
  timeout: 10000
})

// 请求拦截器
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  const token = userSetting.getToken() // 获取token
  if (token) {
    // 请求头添加token
    config.headers.Authorization = token
  }
  return config // 返回配置
}, (error: AxiosError) => {
  promptAction.showToast({ message: error.message })
  return Promise.reject(error)
})

// 响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {
  // 判断业务状态码
  if (response.data && response.data.code === 200) {
    return response.data.data
  }
  promptAction.showToast({ message: response.data.msg }) // 弹出错误消息
  return Promise.reject(new Error(response.data.msg))


}, (error: AxiosError) => {
  // 响应失败
  if (error.response?.status === 401) {
    promptAction.showToast({ message: '登录失败' })
    // 删除token
    userSetting.setToken('') // 清空token
    // 跳转到登录页
    router.replaceUrl({
      url: 'pages/Login/Login'
    })
    // 返回失败
    return Promise.reject(new Error("登录失败"))
  } else if (error.response?.status === 404) {
    promptAction.showToast({ message: '请求地址错误' })
    return Promise.reject(new Error("请求地址错误"))
  }
  promptAction.showToast({ message: error.message })
  return Promise.reject(error)
})

// 封装axios
class Http {
  // 万能请求
  request<ResponseData, Data = Object>(config: AxiosRequestConfig<Data>) {
    return instance.request<null, ResponseData, Data>(config)
  }
  // 封装get请求
  get<ResponseData, Data = undefined>(url: string, params?: Data): Promise<ResponseData> {
    return this.request<ResponseData>({
      url,
      method: 'GET',
      params
    })
  }
  // 封装post请求
  post<ResponseData, Data = undefined>(url: string, data?: Data): Promise<ResponseData> {
    return this.request<ResponseData, Data>({
      url,
      method: 'POST',
      data
    })
  }
  // 封装delete请求
  delete<ResponseData, Data = undefined>(url: string, params?: Data): Promise<ResponseData> {
    return this.request<ResponseData>({
      url,
      method: 'DELETE',
      params
    })
  }
  // 封装put请求
  put<ResponseData, Data = undefined>(url: string, data?: Data): Promise<ResponseData> {
    return this.request<ResponseData, Data>({
      url,
      method: 'PUT',
      data
    })
  }
}

// 导出封装类
export const myHttp = new Http()

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐