赞
踩
- 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自动导入
- 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'
- import { defineStore } from 'pinia'
- import { ref } from 'vue'
-
- // 定义 Store
- export const useMemberStore = defineStore(
- 'member',
- () => {
- // 会员信息
- const profile = ref<any>()
-
- // 保存会员信息,登录时使用
- 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)

- <script setup lang="ts">
- import { useMemberStore } from '@/stores'
- import '@/utils/http'
-
- const memberStore = useMemberStore()
-
-
-
- const getData = () => {
- uni.request({
- method: 'GET',
- url: '/category/top',
- header: {
-
- },
- })
- }
-
- </script>
-
- <template>
- <view class="my">
- <view>会员信息:{{ memberStore.profile }}</view>
- <button @tap="
- memberStore.setProfile({
- nickname: '黑马先锋',
- token: '123'
- })
- " size="mini" plain type="primary">
- 保存用户信息
- </button>
- <button @tap="memberStore.clearProfile()" size="mini" plain type="warn">清理用户信息</button>
- <button @tap="getData()" size="mini" plain type="warn">发起请求</button>
-
- </view>
- </template>
-
- <style lang="scss">
- //
- </style>

- 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<T> {
- code: string
- msg: string
- result: T
- }
-
- //step.2 定义出http 使用泛型
- export const http = <T>(options: UniApp.RequestOptions) => {
- //返回Promise
- return new Promise<Data<T>>((resolve, reject) => {
- uni.request({
- ...options,
- //step.3 响应成功
- success(res) {
- //如果状态码是2xx || 3xx 才会进入resolve
- if (res.statusCode >= 200 && res.statusCode < 300) {
- resolve(res.data as Data<T>)
- } 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<T>).msg || '请求错误',
- icon: 'none',
- mask: true
- })
- reject(res)
- }
-
- },
- //step.4 响应失败
- fail(err) {
- reject(err)
- uni.showToast({
- icon: 'none',
- title: '网络错误,换个网络试试'
- })
- }
- })
- })
- }

测试请求路径不存在
- <script setup lang="ts">
- import { useMemberStore } from '@/stores'
- import { http } from '@/utils/http'
-
- const memberStore = useMemberStore()
-
- const getData = async () => {
- const res = await http<string[]>({
- method: 'GET',
- url: '/category/top123',
- header: {},
- })
- console.log(res)
- }
- </script>
-
- <template>
- <view class="my">
- <view>会员信息:{{ memberStore.profile }}</view>
- <button @tap="
- memberStore.setProfile({
- nickname: '黑马先锋',
- token: '123',
- })
- " size="mini" plain type="primary">
- 保存用户信息
- </button>
- <button @tap="memberStore.clearProfile()" size="mini" plain type="warn">清理用户信息</button>
- <button @tap="getData()" size="mini" plain type="warn">发起请求</button>
- </view>
- </template>
-
- <style lang="scss">
- //
- </style>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。