uniapp+vue3實(shí)現(xiàn)自定義封裝支付密碼組件
更新時間:2025年08月18日 11:11:58 作者:Pinia_0819
本文介紹使用Vue3語法在uniapp中自定義封裝支付密碼組件,通過父組件與子組件的交互實(shí)現(xiàn)密碼輸入功能,并附效果圖展示,感興趣的朋友跟隨小編一起看看吧
使用uniapp自定義封裝支付密碼組件(vue3語法)
父組件
<paypassword v-model="passwordValue" @complete="onPasswordComplete"></paypassword>
const passwordValue = ref('')
// 密碼輸入完成回調(diào)
const onPasswordComplete = (password) => {
console.log('密碼輸入完成:', password)
passwordValue.value = password;
uni.showToast({
title: '密碼輸入完成',
icon: 'success'
})
}子組件
<template>
<view class="password-container">
<!-- 第一行: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': currentIndex === index - 1 }"
>
<view v-if="password[index - 1]" class="password-dot"></view>
</view>
</view>
</view>
<!-- 第二行:狀態(tài)圖標(biāo)和文字 -->
<view class="password-status">
<uni-icons
:type="isCompleted ? 'checkbox-filled' : 'checkbox-filled'"
:color="isCompleted ? '#12a58c' : '#d4d4d4'"
size="32rpx"
></uni-icons>
<text
class="status-text"
:class="{ 'status-text-complete': isCompleted }"
>
{{ '6個數(shù)字' }}
</text>
</view>
<!-- 第三模塊:12宮格數(shù)字鍵盤 -->
<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>
<!-- 移除按鈕可以使用icon,也可以使用自定義圖片我使用的是自定義圖片 -->
<!-- <uni-icons
v-if="key.type === 'delete'"
type="closeempty"
size="56rpx"
color="#171717"
></uni-icons> -->
<image class="delImg" v-if="key.type === 'delete'" src="/static/image/home/Frame.png" mode=""></image>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'
// 定義props
const props = defineProps({
// 提示文字
tipText: {
type: String,
default: '請輸入6位數(shù)字密碼'
},
// 初始密碼值
modelValue: {
type: String,
default: ''
}
})
// 定義emits
const emits = defineEmits(['update:modelValue', 'complete'])
// 數(shù)據(jù)狀態(tài)
const password = ref([])
const currentIndex = ref(0)
// 鍵盤布局
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 isCompleted = computed(() => password.value.length === 6)
// 監(jiān)聽密碼完成狀態(tài)
watch(isCompleted, (newVal) => {
if (newVal) {
const passwordStr = password.value.join('')
emits('update:modelValue', passwordStr)
emits('complete', passwordStr)
}
})
// 監(jiān)聽modelValue變化
watch(() => props.modelValue, (newVal) => {
if (newVal && newVal.length <= 6) {
password.value = newVal.split('')
currentIndex.value = password.value.length
}
}, { immediate: true })
// 處理按鍵點(diǎn)擊
const handleKeyClick = (key) => {
if (key.type === 'number') {
// 輸入數(shù)字
if (password.value.length < 6) {
password.value.push(key.value)
currentIndex.value = password.value.length
}
} else if (key.type === 'delete') {
// 刪除
if (password.value.length > 0) {
password.value.pop()
currentIndex.value = password.value.length
}
}
// 更新modelValue
const passwordStr = password.value.join('')
emits('update:modelValue', passwordStr)
}
// 重置密碼
const resetPassword = () => {
password.value = []
currentIndex.value = 0
}
// 暴露方法給父組件
defineExpose({
resetPassword
})
</script>
<style lang="scss" scoped>
.password-container {
width: 100%;
padding-top: 96rpx;
box-sizing: border-box;
.password-input-container {
margin-bottom: 32rpx;
.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;
&.active {
border-color: #FF4001;
}
.password-dot {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background: #333;
}
}
}
}
.password-status {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.status-text {
font-family: PingFang SC, PingFang SC;
font-size: 24rpx;
color: #737373;
margin-left: 8rpx;
}
.status-text-complete {
color: #12a58c;
}
}
.number-keyboard {
.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;
}
&.key-delete {
// background: #e0e0e0;
}
&.key-empty {
// background: transparent;
// visibility: hidden;
}
}
}
}
}
</style>效果圖:


到此這篇關(guān)于uniapp+vue3實(shí)現(xiàn)自定義封裝支付密碼組件的文章就介紹到這了,更多相關(guān)vue自定義支付密碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Vue.js之視圖和數(shù)據(jù)的雙向綁定(v-model)
本篇文章主要介紹了Vue.js之視圖和數(shù)據(jù)的雙向綁定(v-model),使用v-model指令,使得視圖和數(shù)據(jù)實(shí)現(xiàn)雙向綁定,有興趣的可以了解一下2017-06-06
Vue項目中scrollIntoView導(dǎo)致的布局異常問題解決辦法
scrollIntoView的實(shí)現(xiàn)原理是通過調(diào)整滾動容器的滾動位置,使目標(biāo)元素在視口中可見,這篇文章主要介紹了Vue項目中scrollIntoView導(dǎo)致的布局異常問題解決辦法的相關(guān)資料,需要的朋友可以參考下2026-04-04
Vue Router中獲取路由傳遞過來的參數(shù)(方法詳解)
在VueRouter中,可以通過動態(tài)路由匹配和查詢參數(shù)`query`來傳遞參數(shù),并將路由參數(shù)或查詢參數(shù)作為組件的`props`傳遞,動態(tài)路由匹配使用`route.params`訪問參數(shù),查詢參數(shù)使用`route.query`訪問,本文給大家介紹Vue Router中獲取路由傳遞過來的參數(shù),感興趣的朋友一起看看吧2025-02-02
vue中實(shí)現(xiàn)點(diǎn)擊空白區(qū)域關(guān)閉彈窗的兩種方法
這篇文章主要介紹了vue中實(shí)現(xiàn)點(diǎn)擊空白區(qū)域關(guān)閉彈窗的兩種方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12
組件中多個el-upload存在導(dǎo)致上傳圖片失效的問題及解決
這篇文章主要介紹了組件中多個el-upload存在導(dǎo)致上傳圖片失效的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

