使用uniapp自定义组件双重支付密码

自定义组件双重支付密码

父组件

<template><view class="container"><view class="top"></view><navbar navTitle="修改支付密码"></navbar><!-- 双重支付密码 --><view class="box">//核心代码<paypassworddouble v-model="passwordValue" @complete="onPasswordComplete"></paypassworddouble></view></view>
</template><script setup>import { ref } from 'vue'import navbar from '@/pages/components/navbar.vue'import paypassworddouble from '../components/paypassworddouble.vue' //核心代码const passwordValue = ref('')// 密码输入完成回调const onPasswordComplete = (password) => {console.log('密码输入完成获取最新密码:', password)passwordValue.value = password;// uni.showToast({//   title: '支付密码修改完成',//   icon: 'success'// })}</script><style lang="scss" scoped>.container{width: 750rpx;height: 100%;background: #ffffff;.top{width: 100%;height: 88rpx;}.box{padding: 0 48rpx;}}       
</style>

子组件 全部复制过去直接用就完事了

<template><!-- 双重验证支付密码组件 --><view class="password-container"><!-- 第一行:标题"请输入支付密码" --><view class="password-title">请输入支付密码</view><view class="password-tips">为了您的财产安全考虑,请输入您的支付密码进入!</view><!-- 第二行:6个密码输入框(第一组密码) --><view class="password-input-container"><view class="password-input-row"><view v-for="index in 6" :key="index"class="password-input-box":class="{ 'active': currentInputGroup === 1 && currentFirstIndex === index - 1 }"><view v-if="firstPassword[index - 1]" class="password-text">{{ firstPassword[index - 1] }}</view><view v-else-if="firstPassword[index - 1] === ''" class="password-dot"></view></view></view></view><!-- 第三行:标题"请确认支付密码" --><view class="password-title">请确认支付密码</view><view class="password-tips">为了确认支付密码是否正确,请再次输入!</view><!-- 第四行:6个密码输入框(第二组密码) --><view class="password-input-container password-input-container-two"><view class="password-input-row"><view v-for="index in 6" :key="index"class="password-input-box":class="{ 'active': currentInputGroup === 2 && currentSecondIndex === index - 1 }"><view v-if="secondPassword[index - 1]" class="password-text">{{ secondPassword[index - 1] }}</view><view v-else-if="secondPassword[index - 1] === ''" class="password-dot"></view></view></view></view><!-- 第五行:12宫格数字键盘 --><view class="number-keyboard"><view class="keyboard-row" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex"><view v-for="(key, keyIndex) in row" :key="keyIndex"class="keyboard-key"@click="handleKeyClick(key)"><text v-if="key.type === 'number'" class="key-text">{{ key.value }}</text><image class="delImg" v-if="key.type === 'delete'" src="/static/image/home/Frame.png" mode=""></image></view></view></view><!-- 密码一致性提示 --><view class="password-match-tip" v-if="showMatchTip"><view v-if="isPasswordMatch && secondPassword.length === 6" class="tip-success"><uni-icons type="checkbox-filled" size="28rpx" color="#12a58c"></uni-icons><text class="tip-text success">两次密码输入一致</text></view><view v-else-if="!isPasswordMatch && secondPassword.length === 6" class="tip-error"><uni-icons type="info-filled" size="28rpx" color="#ff0000"></uni-icons><text class="tip-text error">两次密码输入不一致</text></view></view></view>
</template><script setup>
import { ref, computed, watch } from 'vue'// 定义props
const props = defineProps({modelValue: {type: String,default: ''}
})// 定义emits
const emits = defineEmits(['update:modelValue', 'complete', 'match'])// 数据状态
const firstPassword = ref([])  // 第一组密码
const secondPassword = ref([]) // 第二组密码
const currentFirstIndex = ref(0)   // 第一组当前输入位置
const currentSecondIndex = ref(0)  // 第二组当前输入位置
const currentInputGroup = ref(1)   // 当前输入组(1:第一组, 2:第二组)
const isCompleted = ref(false)     // 是否完成输入// 键盘布局
const keyboardLayout = [[{ type: 'number', value: '1' },{ type: 'number', value: '2' },{ type: 'number', value: '3' }],[{ type: 'number', value: '4' },{ type: 'number', value: '5' },{ type: 'number', value: '6' }],[{ type: 'number', value: '7' },{ type: 'number', value: '8' },{ type: 'number', value: '9' }],[{ type: 'number', value: '*' },{ type: 'number', value: '0' },{ type: 'delete'}]
]// 计算属性:密码是否一致
const isPasswordMatch = computed(() => {return firstPassword.value.join('') === secondPassword.value.join('')
})// 计算属性:第二行输入完成开启匹配是否显示匹配提示
const showMatchTip = computed(() => {return secondPassword.value.length === 6
})// 监听密码完成状态
watch([firstPassword, secondPassword], ([newFirst, newSecond]) => {// 当两组密码都输入完成时if (newFirst.length === 6 && newSecond.length === 6) {isCompleted.value = trueconst firstPwd = newFirst.join('')const secondPwd = newSecond.join('')// 检查密码是否一致if (firstPwd === secondPwd) {emits('update:modelValue', firstPwd)emits('complete', firstPwd)emits('match', true)} else {emits('match', false)}} else {isCompleted.value = false}
},{ deep: true })
// 处理按键点击
const handleKeyClick = (key) => {if (key.type === 'number') {// 输入数字if (currentInputGroup.value === 1 && firstPassword.value.length < 6) {firstPassword.value.push(key.value)currentFirstIndex.value = firstPassword.value.length// 第一组输入完成后自动切换到第二组if (firstPassword.value.length === 6) {currentInputGroup.value = 2}} else if (currentInputGroup.value === 2 && secondPassword.value.length < 6) {secondPassword.value.push(key.value)currentSecondIndex.value = secondPassword.value.length}} else if (key.type === 'delete') {// 删除逻辑优化if (currentInputGroup.value === 1 && firstPassword.value.length > 0) {// 删除第一组密码firstPassword.value.pop()currentFirstIndex.value = firstPassword.value.length} else if (currentInputGroup.value === 2 && secondPassword.value.length > 0) {// 删除第二组密码secondPassword.value.pop()currentSecondIndex.value = secondPassword.value.length} else if (currentInputGroup.value === 2 && secondPassword.value.length === 0 && firstPassword.value.length === 6) {// 当第二组密码为空时,切换回第一组currentInputGroup.value = 1currentFirstIndex.value = firstPassword.value.length}}
}// 重置密码
const resetPassword = () => {firstPassword.value = []secondPassword.value = []currentFirstIndex.value = 0currentSecondIndex.value = 0currentInputGroup.value = 1isCompleted.value = false
}// 暴露方法给父组件
defineExpose({resetPassword
})
</script><style lang="scss" scoped>
.password-container {width: 100%;padding-top: 60rpx;box-sizing: border-box;.password-title {height: 56rpx;font-family: PingFang SC, PingFang SC;font-weight: 600;font-size: 56rpx;color: #171717;line-height: 56rpx;margin-bottom: 16rpx;}.password-tips {height: 42rpx;font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 28rpx;color: #737373;line-height: 42rpx;margin-bottom: 48rpx;}.password-input-container {margin-bottom: 48rpx;.password-input-row {display: flex;justify-content: space-between;.password-input-box {width: 96rpx;height: 112rpx;border-radius: 24rpx;border: 2rpx solid #171717;display: flex;align-items: center;justify-content: center;position: relative;&.active {border-color: #FF4001;}.password-text {font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 48rpx;color: #171717;}.password-dot {width: 20rpx;height: 20rpx;border-radius: 50%;background: #333;}}}}.password-input-container-two{margin-bottom: 156rpx;}.number-keyboard {margin-top: 40rpx;.keyboard-row {display: flex;justify-content: space-around;margin-bottom: 20rpx;.keyboard-key {width: 207rpx;height: 112rpx;background: #FAFAFA;border-radius: 24rpx;display: flex;align-items: center;justify-content: center;.key-text {font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 48rpx;color: #171717;}.delImg {width: 56rpx;height: 56rpx;}}}}.password-match-tip {margin-top: 30rpx;display: flex;justify-content: center;.tip-success, .tip-error {display: flex;align-items: center;.tip-text {font-size: 24rpx;margin-left: 10rpx;}.tip-text.success {color: #12a58c;}.tip-text.error {color: #ff0000;}}}
}
</style>

效果图
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93521.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言+安全函数+非安全函数

在C语言中&#xff0c;许多标准库函数&#xff08;如 strcpy、scanf、gets 等&#xff09;由于缺乏边界检查&#xff0c;容易导致 ​缓冲区溢出&#xff08;Buffer Overflow&#xff09;​、内存越界访问​ 等安全问题。为了解决这些问题&#xff0c;C11标准引入了 ​安全函数&…

android build.gradle中的namespace和applicationId的区别

namespace 和 applicationId 确实容作用&#xff1a;1. namespace引入版本&#xff1a;Android Gradle Plugin (AGP) 7.0 开始引入&#xff0c;替代 AndroidManifest.xml 里的 package 属性。作用&#xff1a; 用于 代码中的 R 文件、BuildConfig 生成的 Java/Kotlin 包名。决定…

数据结构初阶(15)排序算法—交换排序(快速排序)(动图演示)

2.3 交换排序 2.3.0 基本思想交换排序的基本思想&#xff1a;基本思想根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。&#xff08;比较结果→交换位置&#xff09;特点将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。比 换…

Apache Hudi:数据湖的实时革命

Apache Hudi是一个开源的数据湖存储格式和框架&#xff0c;它通过引入类似数据库的事务机制&#xff0c;解决了传统数据湖在实时更新、低延迟查询和增量消费方面的痛点。Hudi最初由Uber于2016年开发并应用于生产环境&#xff0c;2017年开源&#xff0c;2019年成为Apache孵化项目…

深度解析和鲸社区热门项目:电商双 11 美妆数据分析的细节与价值

在数据驱动决策的时代&#xff0c;电商大促期间的行业数据分析总能为从业者和学习者提供宝贵参考。今天&#xff0c;我们来详细拆解和鲸社区&#xff08;heywhale&#xff09;上一个备受关注的实战项目 ——《电商双 11 美妆数据分析》&#xff0c;看看它能给我们带来哪些启发。…

uniapp 开发微信小程序,获取经纬度并且转化详细地址(单独封装版本)

目录1、单独抽离封装2、使用示例3、前置条件和配置4、效果弹框1、单独抽离封装 // 腾讯地图SDK引入&#xff08;需提前下载qqmap-wx-jssdk.min.js文件&#xff09; // 注意&#xff1a;使用前需在微信公众平台配置request合法域名https://apis.map.qq.com var QQMapWX requir…

深入理解 Python 元类中的 __prepare__ 方法:掌控类属性定义顺序的艺术

关键词&#xff1a;元类、type、prepare、OrderedDict、属性顺序、数据建模在 Python 的高级编程中&#xff0c;元类&#xff08;metaclass&#xff09; 是一种强大而神秘的机制。它允许我们在类创建之前进行干预&#xff0c;从而实现诸如自动属性验证、字段序列化、ORM 映射等…

MATLAB基础训练实验

MATLAB基础训练实验 1. 标题 MATLAB 基础训练 2. 内容概括 本实验旨在通过MATLAB基础操作训练,掌握数组创建与运算、矩阵操作、M文件编写、流程控制、二维/三维绘图等核心技能。实验内容包括复数运算、矩阵变换、函数绘图、结构体创建、电路方程求解、电流波形绘制、三维曲…

implement libwhich for Windows

因为windows没有类似unix的which命令 现在实现尽量跨平台&#xff0c;且stb 风格的libwhich // which.h #ifndef LIBWHICH_H #define LIBWHICH_H#ifdef __cplusplus extern "C" { #endif/** 查找可执行文件在系统中的路径* 参数:* filename - 要查找的可执行文件名…

记与客户端的一次“无谓之争”

一、冲突今天&#xff0c;流程收尾时&#xff0c;客户端为了统计时延&#xff0c;连发两个接口&#xff1a;一个报开始时间&#xff0c;一个报结束时间。我因性能考虑&#xff0c;说&#xff1a;“明明一个接口能搞定&#xff01;”客户端负责人说&#xff1a;“发送两次更合理…

Java Condition 对象 wait 方法使用与修复方案

在 Java 中&#xff0c;java.util.concurrent.locks.Condition 接口提供了类似监视器的方法&#xff08;await(), signal(), signalAll()&#xff09;来实现线程间的协调。正确使用 Condition 对象需要遵循特定模式以避免常见问题。常见问题及修复方案1. 虚假唤醒问题问题&…

​​金仓数据库KingbaseES V9R1C10安装教程 - Windows版详细指南​

文章目录一、前言二、软件下载2.1 下载安装包2.2 下载授权文件三. 安装KingbaseES数据库3.1 解压安装包3.2 运行安装程序3.3 安装步骤详解步骤1&#xff1a;欢迎界面步骤2&#xff1a;许可协议步骤3&#xff1a;添加授权文件步骤4&#xff1a;选择安装路径步骤5&#xff1a;选择…

论文推荐|迁移学习+多模态特征融合

来gongzhonghao【图灵学术计算机论文辅导】&#xff0c;快速拿捏更多计算机SCI/CCF发文资讯&#xff5e;在Cvpr、NeurIPS、AAAI等顶会中&#xff0c;迁移学习多模态特征融合正以“降成本、提性能、省标注”的绝对优势成为最热赛道。面对超大模型全量微调天价算力、异构模态对齐…

接口芯片断电高阻态特性研究与应用分析

摘要&#xff1a; 本文以国科安芯推出的ASM1042 系列通讯接口芯片为例&#xff0c;深入探讨接口芯片断电高阻态特性&#xff0c;涵盖其定义、原理、应用及设计注意事项。通过对相关技术资料的梳理与分析&#xff0c;结合具体芯片实例&#xff0c;阐述高阻态在电路稳定性、设备兼…

数据结构初阶(17)排序算法——非比较排序(计数排序·动图演示)、排序算法总结

2.0 十大排序算法2.5 非比较排序 之前学习的排序算法都是比较排序——借助比较大小&#xff0c;来实现排序。非比较就是不借助比较大小&#xff0c;来实现排序。——小众的、局限的非比较排序大致有这些&#xff1a;计数排序、桶排序、基数排序。桶排序、基数排序在实践中意义不…

VisualStudio2022调试Unity C#代码步骤

一.VS安装Unity开发组件按下图所示安装Unity开发组件二.附加Unity调试程序2.1 先将Unity进入Play模式2.2 VS选择附加Unity调试程序菜单2.3 选择附加的实例三.加入断点测试Update方法中成功进入断点

Zabbix【部署 01】Zabbix企业级分布式监控系统部署配置使用实例(在线安装及问题处理)程序安装+数据库初始+前端配置+服务启动+Web登录

Zabbix使用 1.下载 2.安装 2.1 程序安装 2.2 数据库初始化 2.3 前端配置 2.4 服务启动 3.Web登录 4.总结 安装说明: 本次安装为在线安装,使用数据库为PostgreSQL。 1.下载 由于是在线安装,这次不涉及离线安装包的下载,仅做参考用,点击跳转【下载页面】,下载说明: 版本…

爬机 验证服务器是否拒绝请求

当访问XX网站时返回 418 状态码时&#xff0c;说明服务器识别到了爬虫行为并拒绝了请求。这是网站的反爬机制在起作用&#xff0c;我们可以通过模拟浏览器行为来绕过基础反爬。import requestsurl https://cn.bing.com/# 模拟浏览器的完整请求头&#xff0c;包含更多浏览器标识…

GaussDB 数据库架构师修炼(十三)安全管理(3)-数据库审计

1 数据库审计作用数据库审计机制主要通过对SQL操作或其他操作记录审计日志的方式 &#xff0c;增强数据库系统对非法操作的追溯及举证能力 。高斯数据库提供两种审计特性 &#xff1a;传统审计 &#xff0c;统一审计。2 传统审计传统审计通过GUC参数配置需要对数据库的哪些操作…

C语言(11)—— 数组(超绝详细总结)

Hi&#xff01;冒险者&#x1f60e;&#xff0c;欢迎闯入 C 语言的奇幻异世界&#x1f30c;&#xff01; 我是 ankleless&#x1f9d1;‍&#x1f4bb;&#xff0c;和你一样的闯荡者&#xff5e; 这是我的冒险笔记打怪升级之路——C语言之路&#x1f4d6;&#xff0c;里面有踩过…