专业的编程技术博客社区

网站首页 > 博客文章 正文

Vue3项目实战:像pinia一样优雅的封装组合式函数

baijin 2025-03-25 10:48:00 博客文章 25 ℃ 0 评论
import { reactive } from 'vue'
import * as api from '@/api/index'

/**
 * 获取手机验方式枚举
 */
export enum GetPhoneMethod {
  SMS = 'SMS', // 手机短信
  WeChat = 'WeChat' // 使用微信手机号
}

// 定义 state 类型
interface State {
  method: GetPhoneMethod
  value: string
}

// 定义 actions 类型
interface Actions {
  setPhoneSms: () => void
  setPhoneWeChat: () => void
  setPhoneNumber: (value: string) => void
  isPhoneSms: () => boolean
  isPhoneWeChat: () => boolean
  onGetPhoneNumber: (e: { detail: { errMsg: string; code: string } }) => Promise
}

// 合并类型为 store 类型
type PhoneStore = State & Actions

/**
 * 管理手机号授权的组合式函数
 * @returns PhoneStore 类型,包含 state 和 actions
 */
const usePhoneAuth = (): PhoneStore => {
  const state = reactive({
    method: GetPhoneMethod.SMS,
    value: ''
  })

  const actions: Actions = {
    setPhoneSms: () => {
      state.method = GetPhoneMethod.SMS
    },
    setPhoneWeChat: () => {
      state.method = GetPhoneMethod.WeChat
    },
    setPhoneNumber: (value: string) => {
      state.value = value
    },
    isPhoneSms: () => state.method === GetPhoneMethod.SMS,
    isPhoneWeChat: () => state.method === GetPhoneMethod.WeChat,
    /**
     * 获取微信手机号
     * @param e
     */
    onGetPhoneNumber: async (e: { detail: { errMsg: string; code: string } }) => {
      if (e.detail.errMsg === 'getPhoneNumber:ok') {
        actions.setPhoneWeChat()

        try {
          // 调用后台接口解密手机号
          const res = await api.getPhone({
            code: e.detail.code
          })
          actions.setPhoneNumber(res.data.phoneNumber)
        } catch (error) {
          // 处理错误
          uni.showToast({ title: '获取手机号失败', icon: 'none' })
        }
      } else {
        // 用户拒绝授权
        uni.showToast({ title: '用户拒绝授权', icon: 'none' })
      }
    }
  }

  // 返回代理对象,支持解构
  return new Proxy(state, {
    get(target, key: keyof PhoneStore) {
      return key in actions ? actions[key as keyof Actions] : target[key as keyof State]
    }
  }) as PhoneStore
}

export default usePhoneAuth

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表