今日学习内容
- 安装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自动导入
设置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<any>()// 保存会员信息,登录时使用const setProfile = (val: any) => {profile.value = val}// 清理会员信息,退出时使用const clearProfile = () => {profile.value = undefined}// 记得 returnreturn {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请求开头的则需要拼接apiUrlif (!options.url.startsWith('http')) {options.url = apiUrl + options.url}//配置请求超时时间options.timeout = 10 * 1000//添加请求头options.header = {...options.header,'source-client': 'miniapp'}//添加tokenconst memberStore = useMemberStore()const token = memberStore.profile?.tokenif (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请求开头的则需要拼接apiUrlif (!options.url.startsWith('http')) {options.url = apiUrl + options.url}//配置请求超时时间options.timeout = 10 * 1000//添加请求头options.header = {...options.header,'source-client': 'miniapp',}//添加tokenconst memberStore = useMemberStore()const token = memberStore.profile?.tokenif (token) {options.header.Authorization = token}},
}//添加拦截器 request uploadFile httpInterceptor是配置
uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)//配置请求函数//step.1 先定义出与后端约定返回的数据格式
interface Data<T> {code: stringmsg: stringresult: T
}//step.2 定义出http 使用泛型
export const http = <T>(options: UniApp.RequestOptions) => {//返回Promisereturn new Promise<Data<T>>((resolve, reject) => {uni.request({...options,//step.3 响应成功success(res) {//如果状态码是2xx || 3xx 才会进入resolveif (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>