refactor: 重构多个组件以支持 Vue 3 语法和功能

- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能
- 优化状态管理和事件处理逻辑,简化代码结构
- 更新样式和布局以适应新组件结构
- 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
Yer11214
2026-07-08 18:37:11 +08:00
parent 4d0b0fb5e4
commit 349ffa4f34
189 changed files with 18278 additions and 20758 deletions

View File

@@ -1,227 +1,211 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
绑定手机号码
</h2>
<h2 class="h2">绑定手机号码</h2>
<view class="verification"></view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile">
<up-form
:model="codeForm"
ref="validateCodeForm"
label-position="left"
label-width="180rpx"
>
<view v-if="!phoneVerified">
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item>
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
ref="uCode" @change="codeChange"></u-code>
<view @tap="getCode" class="text-tips">{{ tips }}</view>
</u-form-item>
</up-form-item>
<view class="submit" @click="validatePhone">绑定</view>
<myVerification keep-running @send="verification" class="verification" ref="verification"
business="BIND_MOBILE" />
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-code
unique-key="page-edit"
:seconds="seconds"
@end="onCodeCountdownEnd"
@start="onCodeCountdownStart"
ref="uCodeRef"
@change="onCodeTextChange"
></u-code>
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
</up-form-item>
<view class="submit" @click="submitBindMobile">绑定</view>
<myVerification
keep-running
@send="onVerificationPassed"
class="verification"
ref="verificationRef"
business="BIND_MOBILE"
/>
</view>
</u-form>
</up-form>
</view>
</view>
</template>
<script>
import {
sendMobile,
bindMobile
} from "@/api/login";
import { getUserInfo } from "@/api/members.js";
import storage from "@/utils/storage.js";
<script setup lang="ts">
import { ref, reactive, watch, getCurrentInstance } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { sendMobile, bindMobile } from '@/api/login'
import { getUserInfo } from '@/api/members.js'
import storage from '@/utils/storage.js'
import MyVerification from '@/components/verification/verification.vue'
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
const store = useStore()
const { proxy } = getCurrentInstance()!
const phoneVerified = ref(false)
const verificationPassed = ref(false)
const codeForm = reactive({
mobile: '',
code: '',
username: '',
})
const codeTips = ref('')
const seconds = 69
const validateCodeForm = ref<any>(null)
const uCodeRef = ref<any>(null)
const verificationRef = ref<any>(null)
const codeRules = {
mobile: [
{
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
message: '手机号码不正确',
trigger: ['blur'],
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
step: 0, //当前验证步骤
flage: false, //是否验证码验证
codeForm: {
mobile: "", //手机号
code: "", //验证码
username: "", //用户名
},
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
codeRules: {
mobile: [{
validator: (rule, value, callback) => {
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
trigger: ["blur"],
}, ],
code: [{
min: 4,
max: 6,
required: true,
message: "请输入验证码",
trigger: ["blur"],
}, ],
},
};
},
onLoad(options) {
this.codeForm.username = options.username;
},
onReady() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
watch: {
flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
uni.showLoading({
title: "正在获取验证码",
});
sendMobile(this.codeForm.mobile, "BIND_MOBILE").then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
this.$refs.verification.getCode();
}
})
} else {
this.$u.toast("请倒计时结束后再发送");
}
}
},
],
code: [
{
min: 4,
max: 6,
required: true,
message: '请输入验证码',
trigger: ['blur'],
},
],
}
methods: {
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
onLoad((options) => {
codeForm.username = options?.username || ''
})
// 验证手机号
validatePhone() {
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
bindMobile(this.codeForm).then((res) => {
if (res.data.success) {
this.validateFlage = !this.validateFlage;
// 获取最新的用户信息并更新缓存
getUserInfo().then(userRes => {
if (userRes.data.success) {
storage.setUserInfo(userRes.data.result);
}
// 显示成功提示
uni.showToast({
title: "绑定成功!",
duration: 2000,
icon: "none",
});
// 返回上一页
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
});
}
});
}
});
},
onReady(() => {
validateCodeForm.value?.setRules(codeRules)
})
codeChange(text) {
this.tips = text;
},
end() {
this.flage = false;
this.$refs.verification.getCode()
},
/**获取验证码 */
getCode() {
if (this.tips == "重新获取") {
this.$refs.verification.error(); //发送
}
if (!this.$u.test.mobile(this.codeForm.mobile)) {
uni.showToast({
title: "请输入正确手机号",
icon: "none",
});
return false;
}
if (!this.flage) {
this.$refs.verification.error(); //发送
return false;
}
},
start() {
this.$u.toast("验证码已发送");
this.flage = true;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
watch(verificationPassed, (val) => {
if (!val) return
if (!uCodeRef.value?.canGetCode) {
proxy.$u.toast('请倒计时结束后再发送')
return
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
uni.showLoading({ title: '正在获取验证码' })
sendMobile(codeForm.mobile, 'BIND_MOBILE').then((res) => {
if (store.state.isShowToast) uni.hideLoading()
if (res.data.success) {
uCodeRef.value?.start()
} else {
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
verificationPassed.value = false
verificationRef.value?.getCode()
}
}
})
})
.h2 {
font-size: 40rpx;
font-weight: bold;
}
function onVerificationPassed(val: string) {
verificationPassed.value = val === store.state.verificationKey
}
page {
background: #fff;
}
function submitBindMobile() {
validateCodeForm.value?.validate((valid: boolean) => {
if (!valid) return
bindMobile(codeForm).then((res) => {
if (res.data.success) {
phoneVerified.value = true
getUserInfo().then((userRes) => {
if (userRes.data.success) {
storage.setUserInfo(userRes.data.result)
}
uni.showToast({ title: '绑定成功!', duration: 2000, icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 1000)
})
}
})
})
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
function onCodeTextChange(text: string) {
codeTips.value = text
}
.submit {
background: $light-color;
}
function onCodeCountdownEnd() {
verificationPassed.value = false
verificationRef.value?.getCode()
}
.box-tips {
margin: 0 72rpx;
function requestSmsCode() {
if (codeTips.value === '重新获取') {
verificationRef.value?.error()
}
if (!proxy.$u.test.mobile(codeForm.mobile)) {
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
return
}
if (!verificationPassed.value) {
verificationRef.value?.error()
}
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
function onCodeCountdownStart() {
proxy.$u.toast('验证码已发送')
verificationPassed.value = true
verificationRef.value?.hide()
}
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
::v-deep .u-form-item__body__right__content__slot {
display: flex;
}
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
page {
background: #fff;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>