相关推荐recommended
学习笔记 | 微信小程序项目day02
作者:mmseoamin日期:2024-04-01

今日学习内容

  • 安装uni-ui跟@uni-helper/uni-ui-types
  • 配置pinia持久化
  • 请求工具类的拦截器
  • 请求工具类的请求函数

    安装uni-ui跟@uni-helper/uni-ui-types

    npm install -g cnpm --registry=https://registry.npmmirror.com
    npm set registry https://registry.npmmirror.com
    npm i -g pnpm
    npm i @dcloudio/uni-ui
    //配置ts类型
    pnpm i -D @uni-helper/uni-ui-types

    配置uni-ui自动导入

    学习笔记 | 微信小程序项目day02,第1张

    设置pinia持久化

    1、新建stores/index.ts

    import { createPinia } from 'pinia'
    import persist from 'pinia-plugin-persistedstate'
    // 创建 pinia 实例
    const pinia = createPinia()
    // 使用持久化存储插件
    pinia.use(persist)
    // 默认导出,给 main.ts 使用
    export default pinia
    // 模块统一导出
    export * from './modules/member'
    

    2、在新建store的时候加上持久化的配置

    import { defineStore } from 'pinia'
    import { ref } from 'vue'
    // 定义 Store
    export const useMemberStore = defineStore(
      'member',
      () => {
        // 会员信息
        const profile = ref()
        // 保存会员信息,登录时使用
        const setProfile = (val: any) => {
          profile.value = val
        }
        // 清理会员信息,退出时使用
        const clearProfile = () => {
          profile.value = undefined
        }
        // 记得 return
        return {
          profile,
          setProfile,
          clearProfile,
        }
      },
      // TODO: 持久化
      {
        //网页端的写法
        // persist: true,
        persist: {
          storage: {
            getItem(key) {
              return uni.getStorageSync(key)
            },
            setItem(key, value) {
              uni.setStorageSync(key, value)
            },
          },
        },
      },
    )
    

    请求工具类的拦截器

    配置拦截器并添加

    import { useMemberStore } from "@/stores"
    //api请求地址
    const apiUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
    //初始化拦截器配置
    const httpInterceptor = {
      //拦截前触发
      invoke(options: UniApp.RequestOptions) {
        //如果不是http请求开头的则需要拼接apiUrl
        if (!options.url.startsWith('http')) {
          options.url = apiUrl + options.url
        }
        //配置请求超时时间
        options.timeout = 10 * 1000
        //添加请求头
        options.header = {
          ...options.header,
          'source-client': 'miniapp'
        }
        //添加token
        const memberStore = useMemberStore()
        const token = memberStore.profile?.token
        if (token) {
          options.header.Authorization = token
        }
      }
    }
    //添加拦截器  request uploadFile   httpInterceptor是配置
    uni.addInterceptor('request', httpInterceptor)
    uni.addInterceptor('uploadFile', httpInterceptor)
    

    使用

    
    
    

    请求工具类的请求函数

    import { useMemberStore } from '@/stores'
    //api请求地址
    const apiUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
    //初始化拦截器配置
    const httpInterceptor = {
      //拦截前触发
      invoke(options: UniApp.RequestOptions) {
        //如果不是http请求开头的则需要拼接apiUrl
        if (!options.url.startsWith('http')) {
          options.url = apiUrl + options.url
        }
        //配置请求超时时间
        options.timeout = 10 * 1000
        //添加请求头
        options.header = {
          ...options.header,
          'source-client': 'miniapp',
        }
        //添加token
        const memberStore = useMemberStore()
        const token = memberStore.profile?.token
        if (token) {
          options.header.Authorization = token
        }
      },
    }
    //添加拦截器  request uploadFile   httpInterceptor是配置
    uni.addInterceptor('request', httpInterceptor)
    uni.addInterceptor('uploadFile', httpInterceptor)
    //配置请求函数
    //step.1 先定义出与后端约定返回的数据格式
    interface Data {
      code: string
      msg: string
      result: T
    }
    //step.2 定义出http 使用泛型
    export const http = (options: UniApp.RequestOptions) => {
      //返回Promise
      return new Promise>((resolve, reject) => {
        uni.request({
          ...options,
          //step.3 响应成功
          success(res) {
            //如果状态码是2xx || 3xx 才会进入resolve
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve(res.data as Data)
            } else if (res.statusCode === 401) {
              //清理用户信息并跳转到登录页
              const memberStore = useMemberStore()
              memberStore.clearProfile()
              //跳转登录页
              uni.navigateTo({ url: '/pages/login/login' })
              reject(res)
            } else {
              //其他错误,进行提示
              uni.showToast({
                title: (res.data as Data).msg || '请求错误',
                icon: 'none',
                mask: true
              })
              reject(res)
            }
          },
          //step.4 响应失败
          fail(err) {
            reject(err)
            uni.showToast({
              icon: 'none',
              title: '网络错误,换个网络试试'
            })
          }
        })
      })
    }
    

    测试请求路径不存在