同步数据

This commit is contained in:
2022-06-12 13:09:03 +08:00
parent b8c986c0d8
commit 238db66375
15 changed files with 2380 additions and 1238 deletions

View File

@@ -0,0 +1,307 @@
<template>
<view class="keyboard-content">
<view class="content_">
<view class="title">请输入支付密码</view>
<view class="password-error">
<text v-if="passwordError">对不起您的支付密码不正确请重新输入</text>
</view>
<view class="input-content">
<view class="input_">
<view v-for="item in inputArr">
<view v-if="item === '·'" class="dot"></view>
<text v-else></text>
</view>
</view>
</view>
<!-- <view class="forget" @tap="forgetPass">忘记密码</view> -->
<view class="board-content">
<view class="title_">
<image src="https://z3.ax1x.com/2021/03/31/cApnN4.png" mode=""></image>
<text> DTX 安全键盘 </text>
</view>
<view class="board">
<view class="key" hover-class="hoverStyle" @tap="inputNum(item.id)" :class="{small: item.id === 'cancel' || item.id === 'del'}" v-for="item in boardArr">
<image class="backspace" v-if="item.id === 'del'" src="https://z3.ax1x.com/2021/03/31/cAp1jx.png" mode=""></image>
<text v-else>{{item.text}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '安全键盘',
}
},
data() {
return {
inputArr: ['','','','','',''],
passwordInput: '',
passwordError: false,
boardArr: [
{
id: '1',
text: '1'
},{
id: '2',
text: '2'
},{
id: '3',
text: '3'
},{
id: '4',
text: '4'
},{
id: '5',
text: '5'
},{
id: '6',
text: '6'
},{
id: '7',
text: '7'
},{
id: '8',
text: '8'
},{
id: '9',
text: '9'
},{
id: 'cancel',
text: '取消'
},{
id: '0',
text: '0'
},{
id: 'del',
text: 'del'
},
],
};
},
methods: {
// 输入密码
inputNum(id) {
if(id === 'del'){ // 点击[删除]按钮
this.del()
return
}
if(id === 'cancel'){ // 点击[取消]按钮
this.cancel()
return
}
if(this.passwordInput.length > 11){ // 6位密码输入完毕
return
}
let passwordInput = this.passwordInput
this.passwordInput = passwordInput + id + '|'
console.log(this.passwordInput);
this.initPass()
if(this.passwordInput.length === 12){ // 输入完毕
console.log(this.passwordInput);
this.testPassword()
}
},
// 删除一位
del() {
this.passwordInput = this.passwordInput.substring(0, this.passwordInput.length - 2)
this.initPass()
},
// 取消 可退出输入
cancel() {
this.inputArr = ['','','','','','']
this.passwordInput = ''
this.$emit('close')
},
initPass() {
let arr = this.passwordInput.split('|');
arr.pop()
console.log(arr);
let arr_ = []
for(let i = 0; i< 6; i++){
if(i < arr.length){
arr_.push('·')
}else{
arr_.push('')
}
}
this.inputArr = arr_
},
// 输入完毕之后 验证密码是否正确
testPassword() {
let arr = this.passwordInput.split('|')
arr.pop()
let passStr = arr.join('')
// 测试数据 在此处可添加个人的业务代码
var isTrue = true
if(isTrue) {
this.$emit('success', passStr)
this.passwordError = false
// uni.showToast({
// title: '密码: '+passStr
// })
this.inputArr = ['','','','','','']
this.passwordInput = ''
}else{
this.passwordError = true
this.inputArr = ['','','','','','']
this.passwordInput = ''
}
},
// 点击忘记密码 可跳转页面或自定义业务
forgetPass() {
this.cancel()
uni.showToast({
title: '忘记密码'
})
},
}
}
</script>
<style lang="scss" scoped>
.hoverStyle{
background: #e5e5e5;
}
.keyboard-content{
background: rgba($color: #000000, $alpha: .7);
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: column;
.content_{
background: #FFFFFF;
width: 100%;
.title{
text-align: center;
padding: 20rpx 0;
font-weight: bold;
border-bottom: 1px solid #dddddd;
background: #f7f7f7;
color: #1F2324;
font-size: 30rpx;
letter-spacing: 1rpx;
}
.password-error{
background: #f7f7f7;
padding: 10rpx 0;
display: flex;
justify-content: center;
align-items: center;
color: #F00;
font-size: 12rpx;
}
.input-content{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: #f7f7f7;
.input_{
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #D9D9D9;
background: #ffffff;
>view{
width: 90rpx;
height: 90rpx;
border-right: 1px solid #dddddd;
display: flex;
justify-content: center;
align-items: center;
&:last-child{
border-right: none;
}
.dot{
width: 20rpx;
height: 20rpx;
background: #000000;
border-radius: 50%;
}
}
}
}
.forget{
color: #666;
font-size: 24rpx;
background: #f7f7f7;
padding: 20rpx 40rpx;
display: flex;
justify-content: flex-end;
align-items: center;
}
.board-content{
.title_{
display: flex;
justify-content: center;
align-items: center;
color: #222;
font-size: 20rpx;
padding: 10rpx 0;
>image{
width: 22rpx;
height: 26rpx;
margin-right: 8rpx;
}
}
.board{
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
border-top: 1px solid #f2f2f2;
.key{
height: 110rpx;
flex: 33%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #f2f2f2;
color: #222;
font-size: 50rpx;
border-left: none;
border-top: none;
}
.small{
font-size: 34rpx;
letter-spacing: 2rpx;
background-color: #f7f7f7;
color: #686868;
}
}
}
.backspace{
width: 45rpx;
height: 33rpx;
}
}
}
</style>

75
components/readme.md Normal file
View File

@@ -0,0 +1,75 @@
# 使用方法
```
<x-pay-pwd
ref="xPayPwd"
:type="1"
:maskClick="true"
top="unset"
bottom="0rpx"
:showClose="false"
@change="change"
:showHead="true"
headText="请输入支付密码"
>
<template #center>
<button @click="clear">插槽</button>
</template>
</x-pay-pwd>
```
```
export default {
methods: {
// 监听输入框内容变化
change({password}){
console.log(password)
},
// 清空输入框内容,一般用于密码输错手动清空
clear(){
this.$refs.xPayPwd._clearKey();
}
}
}
```
# 属性
| 字段 | 类型 | 默认 | 描述 |
| --------- | ------- | -------------- | ---------------------------------------- |
| type | Number | 1 | 0原生键盘 1自定义键盘 |
| maskClick | Boolean | true | 是否允许点击蒙版 |
| top | String | 20vh | 中间内容的top值为absolute的top值 |
| bottom | String | 0rpx | 中间内容的bottom值为absolute的bottom值 |
| showClose | Boolean | true | 是否显示关闭按钮 |
| showHead | Boolean | true | 是否显示标题 |
| headText | String | 请输入支付密码 | 标题文本 |
# 事件
| 事件名 | 默认参数 | 描述 |
| ------ | ---------- | -------------------------------- |
| change | {password} | 监听内容输入,参数返回输入的内容 |
# 组件方法
| 方法名 | 描述 |
| ------ | -------------------------------- |
| _open | 打开弹窗 |
| _close | 关闭弹窗 |
| _clearnKey | 请空输入内容 |
# 注意
```
ios下输入框不会自动获取焦点需要手动点击输入区域
```
# 参与贡献
+ xueshuai(xueshuai_12@163.com)
+ Emailxueshuai_12@163.com
+ GitHubGitHub地址
+ QQ交流群1063233592
+ 个人博客:(薛小帅)[http://blog.xueshuai.top]
+ 个人公众号叮当Ding
![叮当Ding](https://img-blog.csdnimg.cn/20210202143040150.png)

View File

@@ -0,0 +1,157 @@
<template>
<view class="content" :class="{show:open}">
<view class="mask" @click="handleMaskClick"></view>
<view class="wrap native" v-if="type === 0" :style="{top:top,bottom:bottom}">
<view class="head" v-if="showHead">{{headText}}<text class="close" v-if="showClose" @click="_close">x</text></view>
<view ref="pwdTxt" class="input" @click="_focusIpt">
<input ref="pwdIpt" class="hide_ipt" type="tel" maxlength="6" v-model="passwordStr" focus @input="_input"/>
<view class="pwd_i" v-for="(item,index) in password" :key="index"><text class="pwd" v-if="item"></text></view>
</view>
<slot name="center"/>
</view>
<view class="wrap custom" v-if="type === 1" :style="{top:top,bottom:bottom}">
<view class="head" v-if="showHead">{{headText}}<text class="close" v-if="showClose" @click="_close">x</text></view>
<view class="input">
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[0]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[1]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[2]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[3]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[4]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[5]" disabled />
</view>
<slot name="center"/>
<view class="key">
<view class="key_i" v-for="(key,index) in keys" :key="index" :class="{nobg:key == '' || key == 'del',del:key == 'del'}" @click="inputKey(key)">
<text v-if="key != 'del'">{{key}}</text>
<text v-else class="text">x</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
props:{
maskClick:{//是否允许点击蒙版
type:Boolean,
default:true
},
top:{//absoute的top值
type:String,
default:'20vh'
},
bottom:{//absoulute的bottom值
type:String,
default:'0rpx'
},
showClose:{//是否显示关闭按钮
type:Boolean,
default:true
},
type:{//密码支付类型 0原生输入框 1自定义输入框
type:Number,
default:1
},
showHead:{//是否显示头部信息
type:Boolean,
default:true
},
headText:{//头部信息文字
type:String,
default:'请输入支付密码'
}
},
data(){
return{
passwordStr:'',//原生需要的字符串密码
password:['','','','','',''],//原生键盘输入的密码
open:false,//是否展示
pwdArr:[],//自定义支付输入的密码
keys:['1','2','3','4','5','6','7','8','9','','0','del'],//键盘
}
},
methods:{
_input(){// 监听输入
const pwdArr = this.passwordStr.split('');
for(let i = 0;i<6;i++){
this.password[i] = pwdArr[i];
}
if(this.password.length == 6){
this.$emit('change',{password:this.password.join('')})
}
},
_focusIpt(){// 监听点击按钮使输入框获得焦点
this.$refs.pwdIpt._focus();
},
_open(){// 打开弹窗
this.open = true;
},
_close(){// 关闭弹窗
this.open = false;
},
_clearKey(){// 清空输入
this.passwordStr = '';
this.pwdArr = [];
for(let i = 0;i<6;i++){
this.password[i] = '';
}
},
handleMaskClick(){//点击蒙版
if(!this.maskClick) return;
this._close();
},
inputKey(k){// 监听自定义输入
if(k == '') return;
if(k != 'del'){
if(this.pwdArr.length == 6) return;
this.pwdArr.push(k);
}else{
if(this.pwdArr.length == 0) return;
this.pwdArr.splice(this.pwdArr.length-1,1)
}
this.$emit('change',{password:this.pwdArr.join('')})
},
}
}
</script>
<style lang="scss" scoped>
.content{position: fixed;top: 0rpx;right: 0rpx;bottom: 0rpx;left: 0rpx; justify-content: center;display: flex;transition:.3s;transform: scale3d(0, 0, 0);
&.show{transform: scale3d(1,1,1);}
.mask{position: absolute;top: 0;right: 0;bottom: 0;left: 0;background-color: rgba($color: #000000, $alpha: 0.6);z-index:1;}
.wrap{background-color: #fff;border-radius: 16rpx;padding: 40rpx;height: max-content;z-index: 2;position: absolute;width: 70%;
.head{text-align: center;font-size: 36rpx;color: #2B2B2B;font-weight: 500;margin-bottom: 36rpx;position: relative;
.close{position: absolute;right: 0rpx;top: 0rpx;width: 40rpx;height: 40rpx;font-size: 32rpx;color: #646464;display: inline-block;}
}
.input{display: flex;margin: 0rpx 0rpx 16rpx;border: 2rpx solid #F1F1F1;border-radius: 16rpx;justify-content: center;position: relative;
.pwd_i{width: 88rpx;height: 88rpx;border-right:2rpx solid #F1F1F1;text-align: center;font-size: 50rpx;display: flex;align-items: center;justify-content: center;
&:last-of-type{border-right:none;}
.pwd{display: inline-block;width: 18rpx;height: 18rpx;background-color: #000;border-radius: 50%;}
}
.hide_ipt{position: absolute;top: 0rpx;right: 0rpx;bottom: 0rpx;left: -100%;height: auto;color: transparent;z-index: -99;}
}
}
.custom{width: 100%;border-radius: 16rpx 16rpx 0rpx 0rpx;padding: 40rpx 0rpx 0rpx;
.head>.close{right: 20rpx;}
.input{display: flex;margin: 0rpx 41rpx 16rpx;border: 2rpx solid #F1F1F1;border-radius: 16rpx;justify-content: center;
.pwd_i{width: 108rpx;height: 108rpx;border-right:2rpx solid #F1F1F1;text-align: center;font-size: 50rpx;
&:last-of-type{border-right:none;}
}
}
.key{padding: 14rpx 12rpx 0rpx;background-color: #D2D5DB;display: flex;flex-wrap: wrap;
.key_i{width: 234rpx;height: 92rpx;margin-right: 12rpx;text-align: center;line-height: 92rpx;background-color: #fff;margin-bottom: 14rpx;
border-radius: 10rpx;box-shadow: 0px 2px 0px 0px rgba(132,134,136,1);font-size: 50rpx;color: #000000;font-weight: 500;
&:nth-of-type(3n){margin-right: 0rpx;}
&.nobg{background-color: transparent;box-shadow: none;}
&.del{display: flex;justify-content: center;align-items: center;
.text{color: #3F434A;}
}
&:active{box-shadow: 4rpx 4rpx 5rpx #444;background-color: rgba($color: #000000, $alpha: 0.2);}
}
}
}
}
</style>