Files
gym-manage/gym-manage-uniapp/components/global/LoginModal.usage.md
T
2026-06-28 14:49:21 +08:00

5.3 KiB
Raw Blame History

/**

  • 登录弹窗组件使用示例
  • 该组件提供了统一的登录拦截功能,可以在任何页面使用 */

方式一:在页面中直接使用LoginModal组件

<template>
  <view>
    <!-- 其他内容 -->

    <!-- 引入登录弹窗 -->
    <LoginModal
      ref="loginModalRef"
      v-model="showLoginModal"
      title="登录后享受更多服务"
      subtitle="登录即表示同意相关协议"
      :show-close="true"
      :mask-closable="true"
      @loginSuccess="onLoginSuccess"
      @loginError="onLoginError"
    />
  </view>
</template>

<script setup>
import { ref, nextTick } from 'vue'
import { registerLoginModal } from '@/common/hooks/useLoginGuard.js'
import LoginModal from '@/components/global/LoginModal.vue'

const showLoginModal = ref(false)
const loginModalRef = ref(null)

// 注册到全局
onMounted(() => {
  nextTick(() => {
    if (loginModalRef.value) {
      registerLoginModal(loginModalRef.value)
    }
  })
})

// 显示登录弹窗
function showLogin() {
  showLoginModal.value = true
}

// 登录成功回调
function onLoginSuccess(result) {
  console.log('登录成功', result)
  // 刷新页面数据等
}

// 登录失败回调
function onLoginError(error) {
  console.log('登录失败', error)
}
</script>

方式二:使用 useLoginGuard Hook

<script setup>
import { useLoginGuard } from '@/common/hooks/useLoginGuard.js'

const { requireLogin, checkLogin } = useLoginGuard()

// 示例1:需要登录才能执行的操作
async function handleBookCourse() {
  // 检查是否已登录
  if (!checkLogin()) {
    return
  }
  // 执行预约操作...
}

// 示例2:弹窗式登录(推荐)
async function handlePurchase() {
  const loggedIn = await requireLogin({
    title: '请先登录',
    subtitle: '登录后即可购买会员卡',
    onSuccess: (user) => {
      console.log('登录成功,用户信息:', user)
    }
  })

  if (loggedIn) {
    // 执行购买操作
    await purchaseCard()
  }
}

// 示例3:安全执行函数
async function handleCheckIn() {
  const result = await requireLogin().safeExecute(async () => {
    // 只有登录后才能执行这里的代码
    return await checkInApi()
  })

  if (result) {
    uni.showToast({ title: '签到成功' })
  }
}

// 示例4:包装API调用
async function handleGetCoupons() {
  const { callLoggedInApi } = useLoginGuard()

  try {
    const coupons = await callLoggedInApi(getCouponsApi, [], {
      title: '领取优惠券'
    })
    console.log('优惠券列表:', coupons)
  } catch (e) {
    if (e.message === '用户未登录') {
      // 用户未登录,弹窗已显示
    }
  }
}
</script>

方式三:在组件中使用登录守卫Mixin

<script>
import { loginGuardMixin } from '@/common/hooks/useLoginGuard.js'

export default {
  mixins: [loginGuardMixin()],

  methods: {
    async onQuickAction(type) {
      // 自动检查登录状态
      if (!await this.ensureLogin()) {
        return
      }

      // 已登录,执行操作
      if (type === 'book') {
        this.goToBooking()
      }
    }
  }
}
</script>

登录弹窗组件Props说明

属性 类型 默认值 说明
modelValue Boolean false 控制显示/隐藏
title String '登录后享受更多服务' 弹窗标题
subtitle String '登录即表示同意相关协议' 弹窗副标题
showClose Boolean true 是否显示关闭按钮
modalStyle String 'center' 弹窗样式:'center'居中,'bottom'底部
maskClosable Boolean true 点击遮罩是否关闭
onLoginSuccess Function null 登录成功回调
onLoginError Function null 登录失败回调

登录弹窗组件Events

事件名 说明 回调参数
update:modelValue 显示状态变化 Boolean
loginSuccess 登录成功 Object: 登录结果
loginError 登录失败 Error: 错误对象
close 弹窗关闭 -

登录弹窗组件暴露的方法

方法名 说明 参数
show() 显示弹窗 -
hide() 隐藏弹窗 -
switchCard(card) 切换登录方式 'phone'一键登录 / 'sms'验证码登录

全局登录拦截示例

App.vue 中注册全局登录弹窗:

<script>
import LoginModal from '@/components/global/LoginModal.vue'
import { registerLoginModal } from '@/common/hooks/useLoginGuard.js'

export default {
  components: { LoginModal },
  onLaunch() {
    // 注册全局登录弹窗
    this.$nextTick(() => {
      if (this.$refs.globalLoginModal) {
        registerLoginModal(this.$refs.globalLoginModal)
      }
    })
  }
}
</script>

<template>
  <view id="app">
    <router-view />
    <LoginModal ref="globalLoginModal" />
  </view>
</template>

API路径配置

登录弹窗组件使用的API路径定义在 @/api/main.js

// 一键登录
export function phoneLogin(data) {
  return request.post('/auth/phone/login', data)
}

// 短信验证码登录
export function smsLogin(data) {
  return request.post('/auth/phone/sms/login', data)
}

// 发送验证码
export function sendSmsCode(phone) {
  return request.post('/auth/phone/sms/send', { phone })
}

如需修改API路径,请编辑 main.js 文件中的相应函数。