当前位置:   article > 正文

学习笔记 | 微信小程序项目day02_source-client':'miniapp

source-client':'miniapp

今日学习内容

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

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

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

配置uni-ui自动导入

设置pinia持久化

1、新建stores/index.ts

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

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

  1. import { defineStore } from 'pinia'
  2. import { ref } from 'vue'
  3. // 定义 Store
  4. export const useMemberStore = defineStore(
  5. 'member',
  6. () => {
  7. // 会员信息
  8. const profile = ref<any>()
  9. // 保存会员信息,登录时使用
  10. const setProfile = (val: any) => {
  11. profile.value = val
  12. }
  13. // 清理会员信息,退出时使用
  14. const clearProfile = () => {
  15. profile.value = undefined
  16. }
  17. // 记得 return
  18. return {
  19. profile,
  20. setProfile,
  21. clearProfile,
  22. }
  23. },
  24. // TODO: 持久化
  25. {
  26. //网页端的写法
  27. // persist: true,
  28. persist: {
  29. storage: {
  30. getItem(key) {
  31. return uni.getStorageSync(key)
  32. },
  33. setItem(key, value) {
  34. uni.setStorageSync(key, value)
  35. },
  36. },
  37. },
  38. },
  39. )

请求工具类的拦截器

配置拦截器并添加

  1. import { useMemberStore } from "@/stores"
  2. //api请求地址
  3. const apiUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
  4. //初始化拦截器配置
  5. const httpInterceptor = {
  6. //拦截前触发
  7. invoke(options: UniApp.RequestOptions) {
  8. //如果不是http请求开头的则需要拼接apiUrl
  9. if (!options.url.startsWith('http')) {
  10. options.url = apiUrl + options.url
  11. }
  12. //配置请求超时时间
  13. options.timeout = 10 * 1000
  14. //添加请求头
  15. options.header = {
  16. ...options.header,
  17. 'source-client': 'miniapp'
  18. }
  19. //添加token
  20. const memberStore = useMemberStore()
  21. const token = memberStore.profile?.token
  22. if (token) {
  23. options.header.Authorization = token
  24. }
  25. }
  26. }
  27. //添加拦截器 request uploadFile httpInterceptor是配置
  28. uni.addInterceptor('request', httpInterceptor)
  29. uni.addInterceptor('uploadFile', httpInterceptor)

使用

  1. <script setup lang="ts">
  2. import { useMemberStore } from '@/stores'
  3. import '@/utils/http'
  4. const memberStore = useMemberStore()
  5. const getData = () => {
  6. uni.request({
  7. method: 'GET',
  8. url: '/category/top',
  9. header: {
  10. },
  11. })
  12. }
  13. </script>
  14. <template>
  15. <view class="my">
  16. <view>会员信息:{{ memberStore.profile }}</view>
  17. <button @tap="
  18. memberStore.setProfile({
  19. nickname: '黑马先锋',
  20. token: '123'
  21. })
  22. " size="mini" plain type="primary">
  23. 保存用户信息
  24. </button>
  25. <button @tap="memberStore.clearProfile()" size="mini" plain type="warn">清理用户信息</button>
  26. <button @tap="getData()" size="mini" plain type="warn">发起请求</button>
  27. </view>
  28. </template>
  29. <style lang="scss">
  30. //
  31. </style>

请求工具类的请求函数

  1. import { useMemberStore } from '@/stores'
  2. //api请求地址
  3. const apiUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
  4. //初始化拦截器配置
  5. const httpInterceptor = {
  6. //拦截前触发
  7. invoke(options: UniApp.RequestOptions) {
  8. //如果不是http请求开头的则需要拼接apiUrl
  9. if (!options.url.startsWith('http')) {
  10. options.url = apiUrl + options.url
  11. }
  12. //配置请求超时时间
  13. options.timeout = 10 * 1000
  14. //添加请求头
  15. options.header = {
  16. ...options.header,
  17. 'source-client': 'miniapp',
  18. }
  19. //添加token
  20. const memberStore = useMemberStore()
  21. const token = memberStore.profile?.token
  22. if (token) {
  23. options.header.Authorization = token
  24. }
  25. },
  26. }
  27. //添加拦截器 request uploadFile httpInterceptor是配置
  28. uni.addInterceptor('request', httpInterceptor)
  29. uni.addInterceptor('uploadFile', httpInterceptor)
  30. //配置请求函数
  31. //step.1 先定义出与后端约定返回的数据格式
  32. interface Data<T> {
  33. code: string
  34. msg: string
  35. result: T
  36. }
  37. //step.2 定义出http 使用泛型
  38. export const http = <T>(options: UniApp.RequestOptions) => {
  39. //返回Promise
  40. return new Promise<Data<T>>((resolve, reject) => {
  41. uni.request({
  42. ...options,
  43. //step.3 响应成功
  44. success(res) {
  45. //如果状态码是2xx || 3xx 才会进入resolve
  46. if (res.statusCode >= 200 && res.statusCode < 300) {
  47. resolve(res.data as Data<T>)
  48. } else if (res.statusCode === 401) {
  49. //清理用户信息并跳转到登录页
  50. const memberStore = useMemberStore()
  51. memberStore.clearProfile()
  52. //跳转登录页
  53. uni.navigateTo({ url: '/pages/login/login' })
  54. reject(res)
  55. } else {
  56. //其他错误,进行提示
  57. uni.showToast({
  58. title: (res.data as Data<T>).msg || '请求错误',
  59. icon: 'none',
  60. mask: true
  61. })
  62. reject(res)
  63. }
  64. },
  65. //step.4 响应失败
  66. fail(err) {
  67. reject(err)
  68. uni.showToast({
  69. icon: 'none',
  70. title: '网络错误,换个网络试试'
  71. })
  72. }
  73. })
  74. })
  75. }

测试请求路径不存在

  1. <script setup lang="ts">
  2. import { useMemberStore } from '@/stores'
  3. import { http } from '@/utils/http'
  4. const memberStore = useMemberStore()
  5. const getData = async () => {
  6. const res = await http<string[]>({
  7. method: 'GET',
  8. url: '/category/top123',
  9. header: {},
  10. })
  11. console.log(res)
  12. }
  13. </script>
  14. <template>
  15. <view class="my">
  16. <view>会员信息:{{ memberStore.profile }}</view>
  17. <button @tap="
  18. memberStore.setProfile({
  19. nickname: '黑马先锋',
  20. token: '123',
  21. })
  22. " size="mini" plain type="primary">
  23. 保存用户信息
  24. </button>
  25. <button @tap="memberStore.clearProfile()" size="mini" plain type="warn">清理用户信息</button>
  26. <button @tap="getData()" size="mini" plain type="warn">发起请求</button>
  27. </view>
  28. </template>
  29. <style lang="scss">
  30. //
  31. </style>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/379390?site
推荐阅读
相关标签
  

闽ICP备14008679号