bindbox-mini/pages/register/register.vue
2025-12-15 11:43:43 +08:00

323 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="register-container">
<!-- 手机号 -->
<view class="input-row">
<text class="label">手机号</text>
<input
type="number"
v-model="phone"
class="input-field"
placeholder="请输入手机号"
/>
</view>
<!-- 密码 -->
<view class="input-row">
<text class="label">密码</text>
<input
type="password"
v-model="pwd"
class="input-field"
placeholder="请输入密码"
/>
</view>
<!-- 确认密码 -->
<view class="input-row">
<text class="label">确认密码</text>
<input
type="password"
v-model="confirmPwd"
class="input-field"
placeholder="请再次输入密码"
/>
</view>
<!-- 手机验证码 -->
<view class="input-row">
<text class="label">验证码</text>
<view class="captcha-container">
<input
type="text"
v-model="userCaptcha"
class="input-field captcha-input"
placeholder="请输入验证码"
/>
<button
class="captcha-btn"
:class="{ disabled: countdown > 0 || !isPhoneValidForCaptcha }"
@click="sendSmsCode"
:disabled="countdown > 0 || !isPhoneValidForCaptcha"
>
{{ countdown > 0 ? `${countdown}秒后重发` : '获取验证码' }}
</button>
</view>
</view>
<!-- 注册按钮 -->
<button
class="btn register-btn"
:class="{ disabled: !canRegister }"
@click="handleRegister"
:disabled="!canRegister"
>
注册
</button>
<!-- 返回登录 -->
<view class="back-link">
<text class="back-text" @click="goToLogin">已有账号点击登录</text>
</view>
</view>
</template>
<script setup>
import { ref, computed, onUnmounted } from 'vue'
// 响应式数据
const account = ref('')
const pwd = ref('')
const confirmPwd = ref('')
const phone = ref('')
const userCaptcha = ref('') // 用户输入的验证码
const smsCode = ref('') // 服务器返回的验证码(模拟)
const countdown = ref(0) // 倒计时
let timer = null // 倒计时定时器
// 计算属性:判断手机号是否有效(用于获取验证码按钮)
const isPhoneValidForCaptcha = computed(() => {
const phoneRegex = /^1[3-9]\d{9}$/
return phone.value.trim() && phoneRegex.test(phone.value)
})
// 计算属性:判断是否可以注册
const canRegister = computed(() => {
// 检查账号、密码、确认密码、手机号和验证码是否都已填写
const isAccountValid = account.value.trim().length >= 6
const isPasswordValid = pwd.value.trim().length > 0
const isConfirmPasswordValid = confirmPwd.value === pwd.value
const isPhoneValid = isPhoneValidForCaptcha.value
const isCaptchaValid = userCaptcha.value.trim().length > 0
return isAccountValid &&
isPasswordValid &&
isConfirmPasswordValid &&
isPhoneValid &&
isCaptchaValid
})
// 发送短信验证码
const sendSmsCode = async () => {
// 验证手机号格式
const phoneRegex = /^1[3-9]\d{9}$/
if (!phone.value.trim()) {
uni.showToast({ title: '请输入手机号', icon: 'none' })
return
}
if (!phoneRegex.test(phone.value)) {
uni.showToast({ title: '手机号格式不正确', icon: 'none' })
return
}
// 模拟发送短信验证码(实际应用中应调用后端接口)
try {
uni.showLoading({ title: '发送中...' })
// 模拟API请求延迟
await new Promise(resolve => setTimeout(resolve, 1000))
// 生成6位数字验证码
const code = Math.floor(100000 + Math.random() * 900000).toString()
smsCode.value = code
console.log('发送的验证码:', code) // 仅用于调试
uni.hideLoading()
uni.showToast({ title: '验证码已发送', icon: 'success' })
// 开始倒计时
startCountdown()
} catch (error) {
uni.hideLoading()
uni.showToast({ title: '验证码发送失败', icon: 'none' })
}
}
// 开始倒计时
const startCountdown = () => {
countdown.value = 60
if (timer) clearInterval(timer)
timer = setInterval(() => {
countdown.value--
if (countdown.value <= 0) {
clearInterval(timer)
timer = null
}
}, 1000)
}
// 注册逻辑
const handleRegister = async () => {
if (!account.value.trim()) {
uni.showToast({ title: '请输入账号', icon: 'none' })
return
}
if (account.value.length < 6) {
uni.showToast({ title: '账号长度不能少于6位', icon: 'none' })
return
}
if (!pwd.value.trim()) {
uni.showToast({ title: '请输入密码', icon: 'none' })
return
}
if (pwd.value !== confirmPwd.value) {
uni.showToast({ title: '两次输入的密码不一致', icon: 'none' })
return
}
// 验证手机号
const phoneRegex = /^1[3-9]\d{9}$/
if (!phone.value.trim()) {
uni.showToast({ title: '请输入手机号', icon: 'none' })
return
}
if (!phoneRegex.test(phone.value)) {
uni.showToast({ title: '手机号格式不正确', icon: 'none' })
return
}
if (!userCaptcha.value.trim()) {
uni.showToast({ title: '请输入验证码', icon: 'none' })
return
}
// 验证验证码
if (userCaptcha.value !== smsCode.value) {
uni.showToast({ title: '验证码错误', icon: 'none' })
return
}
// 这里写你的实际注册请求逻辑(示例)
uni.showLoading({ title: '注册中...' })
try {
// 模拟API请求
await new Promise(resolve => setTimeout(resolve, 1000))
uni.hideLoading()
uni.showToast({ title: '注册成功', icon: 'success' })
// 注册成功后跳转到登录页
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/index'
})
}, 500)
} catch (error) {
uni.hideLoading()
uni.showToast({ title: '注册失败', icon: 'none' })
}
}
// 返回登录页
const goToLogin = () => {
uni.navigateTo({ url: '/pages/login/index' })
}
// 在页面卸载时清除定时器
onUnmounted(() => {
if (timer) {
clearInterval(timer)
}
})
</script>
<style scoped>
.register-container {
padding: 40rpx;
background-color: #fff;
min-height: 100vh;
}
.input-row {
display: flex;
align-items: center;
margin-bottom: 40rpx;
}
.label {
width: 160rpx;
font-size: 32rpx;
color: #333;
}
.input-field {
flex: 1;
height: 80rpx;
border: 2px solid #ccc;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
-webkit-appearance: none;
outline: none;
}
.captcha-container {
display: flex;
align-items: center;
flex: 1;
}
.captcha-input {
flex: 1;
margin-right: 10rpx;
}
.captcha-btn {
width: 180rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background-color: #007aff;
color: #fff;
border: none;
border-radius: 8rpx;
font-size: 24rpx;
}
.captcha-btn.disabled {
background-color: #ccc;
color: #999;
}
.btn {
width: 100%;
height: 80rpx;
border-radius: 8rpx;
font-size: 32rpx;
color: #fff;
background-color: #007aff;
margin-bottom: 30rpx;
}
.btn.disabled {
background-color: #ccc;
}
.back-link {
text-align: center;
}
.back-text {
font-size: 26rpx;
color: #999;
text-decoration: underline;
}
.back-text:active {
color: #007aff;
}
</style>