--- alwaysApply: false --- ### API 设计模式 #### 统一 API 封装 **基础请求封装** ```javascript // utils/request.js const BASE_URL = 'https://api.example.com' const request = { // GET 请求 get(url, params = {}) { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method: 'GET', data: params, header: { 'Authorization': uni.getStorageSync('token'), 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { this.handleError(res) reject(res) } }, fail: (err) => { this.handleError(err) reject(err) } }) }) }, // POST 请求 post(url, data = {}) { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method: 'POST', data: data, header: { 'Authorization': uni.getStorageSync('token'), 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { this.handleError(res) reject(res) } }, fail: (err) => { this.handleError(err) reject(err) } }) }) }, // 统一错误处理 handleError(error) { let message = '请求失败' if (error.statusCode) { switch (error.statusCode) { case 401: message = '登录已过期,请重新登录' // 跳转到登录页 uni.navigateTo({ url: '/pages/login/login' }) break case 403: message = '没有权限访问' break case 404: message = '请求的资源不存在' break case 500: message = '服务器内部错误' break default: message = error.data?.message || '请求失败' } } uni.showToast({ title: message, icon: 'none', duration: 2000 }) } } export default request ``` #### API 模块化组织 **按业务模块组织API** ```javascript // api/user.js import request from '@/utils/request' export const userApi = { // 登录 login(data) { return request.post('/user/login', data) }, // 获取用户信息 getUserInfo() { return request.get('/user/info') }, // 更新用户信息 updateUser(data) { return request.post('/user/update', data) } } // api/order.js export const orderApi = { // 获取订单列表 getOrderList(params) { return request.get('/order/list', params) }, // 创建订单 createOrder(data) { return request.post('/order/create', data) } } ``` #### 数据状态管理模式 **加载状态处理** ```javascript // 在页面或组件中 export default { data() { return { loading: false, list: [], error: null, empty: false } }, methods: { async loadData() { this.loading = true this.error = null try { const result = await orderApi.getOrderList() this.list = result.data || [] this.empty = this.list.length === 0 } catch (error) { this.error = error.message } finally { this.loading = false } } } } ``` **分页加载模式** ```javascript export default { data() { return { list: [], page: 1, pageSize: 20, total: 0, loading: false, loadingMore: false, noMore: false } }, methods: { // 初始加载 async loadData() { this.page = 1 this.loading = true try { const result = await orderApi.getOrderList({ page: this.page, pageSize: this.pageSize }) this.list = result.data || [] this.total = result.total || 0 this.noMore = this.list.length >= this.total } catch (error) { console.error('加载失败:', error) } finally { this.loading = false } }, // 加载更多 async loadMore() { if (this.loadingMore || this.noMore) return this.page += 1 this.loadingMore = true try { const result = await orderApi.getOrderList({ page: this.page, pageSize: this.pageSize }) const newData = result.data || [] this.list = [...this.list, ...newData] this.noMore = this.list.length >= result.total } catch (error) { this.page -= 1 // 回滚页码 console.error('加载更多失败:', error) } finally { this.loadingMore = false } }, // 下拉刷新 async onRefresh() { await this.loadData() uni.stopPullDownRefresh() } } } ``` #### 缓存策略 **数据缓存模式** ```javascript // utils/cache.js export const cache = { // 设置缓存 set(key, data, expire = 3600000) { // 默认1小时 const item = { data, expire: Date.now() + expire } uni.setStorageSync(key, JSON.stringify(item)) }, // 获取缓存 get(key) { try { const item = JSON.parse(uni.getStorageSync(key) || '{}') if (item.expire && Date.now() > item.expire) { uni.removeStorageSync(key) return null } return item.data } catch { return null } }, // 删除缓存 remove(key) { uni.removeStorageSync(key) } } // 在 API 中使用缓存 export const userApi = { async getUserInfo(useCache = true) { const cacheKey = 'user_info' if (useCache) { const cached = cache.get(cacheKey) if (cached) return cached } const result = await request.get('/user/info') cache.set(cacheKey, result) return result } } ``` #### 表单处理模式 **表单验证和提交** ```javascript export default { data() { return { form: { name: '', phone: '', email: '' }, rules: { name: { required: true, message: '请输入姓名' }, phone: { required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }, email: { pattern: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/, message: '请输入正确的邮箱' } }, submitting: false } }, methods: { // 表单验证 validateForm() { for (const field in this.rules) { const rule = this.rules[field] const value = this.form[field] if (rule.required && !value) { uni.showToast({ title: rule.message, icon: 'none' }) return false } if (rule.pattern && value && !rule.pattern.test(value)) { uni.showToast({ title: rule.message, icon: 'none' }) return false } } return true }, // 提交表单 async submitForm() { if (!this.validateForm()) return this.submitting = true try { await userApi.updateUser(this.form) uni.showToast({ title: '保存成功' }) uni.navigateBack() } catch (error) { console.error('提交失败:', error) } finally { this.submitting = false } } } } ``` ### API 设计模式 #### 统一 API 封装 **基础请求封装** ```javascript // utils/request.js const BASE_URL = 'https://api.example.com' const request = { // GET 请求 get(url, params = {}) { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method: 'GET', data: params, header: { 'Authorization': uni.getStorageSync('token'), 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { this.handleError(res) reject(res) } }, fail: (err) => { this.handleError(err) reject(err) } }) }) }, // POST 请求 post(url, data = {}) { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method: 'POST', data: data, header: { 'Authorization': uni.getStorageSync('token'), 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { this.handleError(res) reject(res) } }, fail: (err) => { this.handleError(err) reject(err) } }) }) }, // 统一错误处理 handleError(error) { let message = '请求失败' if (error.statusCode) { switch (error.statusCode) { case 401: message = '登录已过期,请重新登录' // 跳转到登录页 uni.navigateTo({ url: '/pages/login/login' }) break case 403: message = '没有权限访问' break case 404: message = '请求的资源不存在' break case 500: message = '服务器内部错误' break default: message = error.data?.message || '请求失败' } } uni.showToast({ title: message, icon: 'none', duration: 2000 }) } } export default request ``` #### API 模块化组织 **按业务模块组织API** ```javascript // api/user.js import request from '@/utils/request' export const userApi = { // 登录 login(data) { return request.post('/user/login', data) }, // 获取用户信息 getUserInfo() { return request.get('/user/info') }, // 更新用户信息 updateUser(data) { return request.post('/user/update', data) } } // api/order.js export const orderApi = { // 获取订单列表 getOrderList(params) { return request.get('/order/list', params) }, // 创建订单 createOrder(data) { return request.post('/order/create', data) } } ``` #### 数据状态管理模式 **加载状态处理** ```javascript // 在页面或组件中 export default { data() { return { loading: false, list: [], error: null, empty: false } }, methods: { async loadData() { this.loading = true this.error = null try { const result = await orderApi.getOrderList() this.list = result.data || [] this.empty = this.list.length === 0 } catch (error) { this.error = error.message } finally { this.loading = false } } } } ``` **分页加载模式** ```javascript export default { data() { return { list: [], page: 1, pageSize: 20, total: 0, loading: false, loadingMore: false, noMore: false } }, methods: { // 初始加载 async loadData() { this.page = 1 this.loading = true try { const result = await orderApi.getOrderList({ page: this.page, pageSize: this.pageSize }) this.list = result.data || [] this.total = result.total || 0 this.noMore = this.list.length >= this.total } catch (error) { console.error('加载失败:', error) } finally { this.loading = false } }, // 加载更多 async loadMore() { if (this.loadingMore || this.noMore) return this.page += 1 this.loadingMore = true try { const result = await orderApi.getOrderList({ page: this.page, pageSize: this.pageSize }) const newData = result.data || [] this.list = [...this.list, ...newData] this.noMore = this.list.length >= result.total } catch (error) { this.page -= 1 // 回滚页码 console.error('加载更多失败:', error) } finally { this.loadingMore = false } }, // 下拉刷新 async onRefresh() { await this.loadData() uni.stopPullDownRefresh() } } } ``` #### 缓存策略 **数据缓存模式** ```javascript // utils/cache.js export const cache = { // 设置缓存 set(key, data, expire = 3600000) { // 默认1小时 const item = { data, expire: Date.now() + expire } uni.setStorageSync(key, JSON.stringify(item)) }, // 获取缓存 get(key) { try { const item = JSON.parse(uni.getStorageSync(key) || '{}') if (item.expire && Date.now() > item.expire) { uni.removeStorageSync(key) return null } return item.data } catch { return null } }, // 删除缓存 remove(key) { uni.removeStorageSync(key) } } // 在 API 中使用缓存 export const userApi = { async getUserInfo(useCache = true) { const cacheKey = 'user_info' if (useCache) { const cached = cache.get(cacheKey) if (cached) return cached } const result = await request.get('/user/info') cache.set(cacheKey, result) return result } } ``` #### 表单处理模式 **表单验证和提交** ```javascript export default { data() { return { form: { name: '', phone: '', email: '' }, rules: { name: { required: true, message: '请输入姓名' }, phone: { required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }, email: { pattern: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/, message: '请输入正确的邮箱' } }, submitting: false } }, methods: { // 表单验证 validateForm() { for (const field in this.rules) { const rule = this.rules[field] const value = this.form[field] if (rule.required && !value) { uni.showToast({ title: rule.message, icon: 'none' }) return false } if (rule.pattern && value && !rule.pattern.test(value)) { uni.showToast({ title: rule.message, icon: 'none' }) return false } } return true }, // 提交表单 async submitForm() { if (!this.validateForm()) return this.submitting = true try { await userApi.updateUser(this.form) uni.showToast({ title: '保存成功' }) uni.navigateBack() } catch (error) { console.error('提交失败:', error) } finally { this.submitting = false } } } } ```