Skip to content

Commit

Permalink
feat: up-input/up-code组件支持uni-app-x
Browse files Browse the repository at this point in the history
  • Loading branch information
jry committed Aug 30, 2024
1 parent 0a66a48 commit 5011aa2
Show file tree
Hide file tree
Showing 14 changed files with 924 additions and 129 deletions.
68 changes: 23 additions & 45 deletions src/pages/componentsC/input/input.nvue
Original file line number Diff line number Diff line change
Expand Up @@ -105,58 +105,36 @@
<view class="u-demo-block">
<text class="u-demo-block__title">前后插槽</text>
<view class="u-demo-block__content">
<!-- 注意:由于兼容性差异,如果需要使用前后插槽,nvue下需使用u--input,非nvue下需使用u-input -->
<!-- #ifndef APP-NVUE -->
<up-input placeholder="前置插槽">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<up-input placeholder="前置插槽">
<!-- #endif -->
<template #prefix>
<up-text
text="http://"
margin="0 3px 0 0"
type="tips"
></up-text>
</template>
<!-- #ifndef APP-NVUE -->
<template #prefix>
<up-text
text="http://"
margin="0 3px 0 0"
type="tips"
></up-text>
</template>
</up-input>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</up-input>
<!-- #endif -->
</view>
<view
class="u-demo-block__content"
style="margin-top: 15px;"
>
<!-- 注意:由于兼容性差异,如果需要使用前后插槽,nvue下需使用u--input,非nvue下需使用u-input -->
<!-- #ifndef APP-NVUE -->
<up-input placeholder="后置插槽">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<up-input placeholder="后置插槽">
<!-- #endif -->
<template #suffix>
<up-code
ref="uCode"
@change="codeChange"
seconds="20"
changeText="X秒重新获取哈哈哈"
></up-code>
<up-button
@tap="getCode"
:text="tips"
type="success"
size="mini"
></up-button>
</template>
<!-- #ifndef APP-NVUE -->
</up-input>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<template #suffix>
<up-code
ref="upCodeRef"
@change="codeChange"
seconds="20"
changeText="X秒重新获取哈哈哈"
></up-code>
<up-button
@tap="getCode"
:text="tips"
type="success"
size="mini"
></up-button>
</template>
</up-input>
<!-- #endif -->
</view>
</view>
<up-gap
Expand Down Expand Up @@ -189,7 +167,7 @@
this.tips = text;
},
getCode() {
if (this.$refs.uCode.canGetCode) {
if (this.$refs.upCodeRef.canGetCode) {
// 模拟向后端请求验证码
uni.showLoading({
title: '正在获取验证码'
Expand All @@ -199,7 +177,7 @@
// 这里此提示会被this.start()方法中的提示覆盖
uni.$u.toast('验证码已发送');
// 通知验证码组件内部开始倒计时
this.$refs.uCode.start();
this.$refs.upCodeRef.start();
}, 2000);
} else {
uni.$u.toast('倒计时结束后再发送');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { defineMixin } from '../../libs/vue.uts'
import defProps from '../../libs/config/props.uts'
let cellGroup = defProps['cellGroup'] as UTSJSONObject

export const props = defineMixin({
export const propsCellGroup = defineMixin({
props: {
// 分组标题
title: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<template>
<view :style="[addStyle(customStyle)]" :class="[customClass]" class="up-cell-group">
<view :style="[addStyle(customStyle)]"
:class="[customClass]" class="up-cell-group">
<view v-if="title" class="up-cell-group__title">
<slot name="title">
<text class="up-cell-group__title__text">{{ title }}</text>
<text class="up-cell-group__title__text">
{{ title }}
</text>
</slot>
</view>
<view class="up-cell-group__wrapper">
Expand All @@ -13,7 +16,7 @@
</template>

<script>
import { props } from './props';
import { propsCellGroup } from './props';
import { mpMixin } from '../../libs/mixin/mpMixin';
import { mixin } from '../../libs/mixin/mixin';
import { addStyle } from '../../libs/function/index';
Expand All @@ -30,7 +33,7 @@
*/
export default {
name: 'up-cell-group',
mixins: [mpMixin, mixin, props],
mixins: [mpMixin, mixin, propsCellGroup],
methods: {
addStyle(val: any): any {
return addStyle(val)
Expand Down
20 changes: 20 additions & 0 deletions src/uni_modules/uview-plus/components/up-code/code.uts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* @Author : jry
* @Description :
* @version : 4.0
* @Date : 2024-08-28 23:05:58
* @LastAuthor : jry
* @lastTime : 2024-08-28 23:05:58
* @FilePath : /uview-plus/libs/config/props/code.js
*/
export default {
// code 组件
code: {
seconds: 60,
startText: '获取验证码',
changeText: 'X秒重新获取',
endText: '重新获取',
keepRunning: false,
uniqueKey: ''
}
} as UTSJSONObject
47 changes: 47 additions & 0 deletions src/uni_modules/uview-plus/components/up-code/props.uts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* @Author : jry
* @Description :
* @version : 4.0
* @Date : 2024-08-28 23:05:58
* @LastAuthor : jry
* @lastTime : 2024-08-28 23:05:58
* @FilePath : /uview-plus/libs/config/props/code.js
*/
import { defineMixin } from '../../libs/vue'
import defProps from './code'
let crtProp = defProps['code'] as UTSJSONObject

export const propsCode = defineMixin({
props: {
// 倒计时总秒数
seconds: {
type: [Number],
default: crtProp['seconds']
},
// 尚未开始时提示
startText: {
type: String,
default: crtProp['startText']
},
// 正在倒计时中的提示
changeText: {
type: String,
default: crtProp['changeText']
},
// 倒计时结束时的提示
endText: {
type: String,
default: crtProp['endText']
},
// 是否在H5刷新或各端返回再进入时继续倒计时
keepRunning: {
type: Boolean,
default: crtProp['keepRunning']
},
// 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
uniqueKey: {
type: String,
default: crtProp['uniqueKey']
}
}
})
137 changes: 137 additions & 0 deletions src/uni_modules/uview-plus/components/up-code/up-code.uvue
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<template>
<view class="up-code">
<!-- 此组件功能由js完成,无需写html逻辑 -->
</view>
</template>

<script>
import { propsCode } from './props';
import { mpMixin } from '../../libs/mixin/mpMixin';
import { mixin } from '../../libs/mixin/mixin';
/**
* Code 验证码输入框
* @author jry [email protected]
* @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 不提供界面显示,只提供提示语,由用户将提示语嵌入到具体的场景
* @tutorial https://ijry.github.io/uview-plus/components/code.html
* @property {String | Number} seconds 倒计时所需的秒数(默认 60 )
* @property {String} startText 开始前的提示语,见官网说明(默认 '获取验证码' )
* @property {String} changeText 倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' )
* @property {String} endText 倒计结束的提示语,见官网说明(默认 '重新获取' )
* @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时( 默认false )
* @property {String} uniqueKey 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
*
* @event {Function} change 倒计时期间,每秒触发一次
* @event {Function} start 开始倒计时触发
* @event {Function} end 结束倒计时触发
* @example <up-code ref="uCode" @change="codeChange" :seconds="20"></up-code>
*/
export default {
name: "up-code",
mixins: [mpMixin, mixin, propsCode],
data() {
return {
secNum: this.seconds as number,
timer: 0,
canGetCode: true, // 是否可以执行验证码操作
}
},
mounted() {
this.checkKeepRunning()
},
watch: {
seconds: {
immediate: true,
handler(n: number) {
this.secNum = n
}
}
},
emits: ["start", "end", "change"],
methods: {
checkKeepRunning(): void {
// 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
let lastTimestamp = parseInt(uni.getStorageSync(this.uniqueKey + '_$upCountDownTimestamp').toString())
if(lastTimestamp > 0) {
return this.changeEvent(this.startText)
}
// 当前秒的时间戳
let nowTimestamp = Math.floor(new Date().getTime() / 1000)
// 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
if(this.keepRunning
&& lastTimestamp > 0
&& lastTimestamp > nowTimestamp) {
// 剩余尚未执行完的倒计秒数
this.secNum = lastTimestamp - nowTimestamp
// 清除本地保存的变量
uni.removeStorageSync(this.uniqueKey + '_$upCountDownTimestamp')
// 开始倒计时
this.start()
} else {
// 如果不存在需要继续上一次的倒计时,执行正常的逻辑
this.changeEvent(this.startText)
}
},
// 开始倒计时
start(): void {
// 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
if(this.timer != 0) {
clearInterval(this.timer)
this.timer = 0
}
this.$emit('start')
this.canGetCode = false
// 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
this.changeEvent(this.changeText.replace(/x|X/, this.secNum.toString()))
this.timer = setInterval(() => {
if (this.secNum - 1 > 0) {
// 用当前倒计时的秒数替换提示字符串中的"x"字母
this.changeEvent(this.changeText.replace(/x|X/, (this.secNum - 1).toString()))
} else {
clearInterval(this.timer)
this.timer = 0
this.changeEvent(this.endText)
this.secNum = parseInt(this.seconds.toString())
this.$emit('end')
this.canGetCode = true
}
}, 1000)
this.setTimeToStorage()
},
// 重置,可以让用户再次获取验证码
reset(): void {
this.canGetCode = true
clearInterval(this.timer)
this.secNum = parseInt(this.seconds.toString())
this.changeEvent(this.endText)
},
changeEvent(text: string): void {
this.$emit('change', text)
},
// 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
setTimeToStorage(): void {
if(!this.keepRunning || this.timer == 0) return
// 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
// 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
if(this.secNum > 0 && this.secNum < parseInt(this.seconds.toString())) {
// 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
let nowTimestamp = Math.floor(new Date().getTime() / 1000)
// 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
uni.setStorage({
key: this.uniqueKey + '_$uCountDownTimestamp',
data: (nowTimestamp + this.secNum).toString()
})
}
}
},
// 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
beforeUnmount() {
this.setTimeToStorage()
clearTimeout(this.timer)
this.timer = 0
}
}
</script>

<style lang="scss" scoped>
@import "../../libs/css/components.scss";
</style>
2 changes: 1 addition & 1 deletion src/uni_modules/uview-plus/components/up-code/up-code.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*/
export default {
name: "up-code",
mixins: [mpMixin, mixin,props],
mixins: [mpMixin, mixin, props],
data() {
return {
secNum: this.seconds,
Expand Down
Loading

0 comments on commit 5011aa2

Please sign in to comment.