【ADD】button新增防抖节流模式+附带案例

This commit is contained in:
zhengliming
2023-12-10 12:46:45 +08:00
parent 0564dcd88a
commit 733e71862a
3 changed files with 376 additions and 293 deletions

View File

@@ -14,7 +14,7 @@
<demo-title title="大小"> <demo-title title="大小">
<view> <view>
<tn-button size="sm" margin="10rpx 10rpx">按钮</tn-button> <tn-button size="sm" margin="10rpx 10rpx" >按钮</tn-button>
<tn-button margin="10rpx 10rpx">按钮</tn-button> <tn-button margin="10rpx 10rpx">按钮</tn-button>
<tn-button size="lg" margin="10rpx 10rpx">按钮</tn-button> <tn-button size="lg" margin="10rpx 10rpx">按钮</tn-button>
<tn-button width="150rpx" height="100rpx" :fontSize="40" margin="10rpx 10rpx">按钮</tn-button> <tn-button width="150rpx" height="100rpx" :fontSize="40" margin="10rpx 10rpx">按钮</tn-button>
@@ -78,6 +78,11 @@
<tn-button :disabled="true" width="100%" height="100rpx" margin="10rpx 0">按钮</tn-button> <tn-button :disabled="true" width="100%" height="100rpx" margin="10rpx 0">按钮</tn-button>
</demo-title> </demo-title>
<demo-title title="防抖节流(默认间隔200ms,这里用1s)">
<tn-button width="100%" height="100rpx" margin="10rpx 0" @click="say('点击了防抖')" :blockTime="1000" scene="debounce">防抖模式</tn-button>
<tn-button width="100%" height="100rpx" margin="10rpx 0" @click="say('点击了节流')" :blockTime="1000" scene="throttle">节流模式</tn-button>
</demo-title>
<view class="tn-padding-bottom-lg"></view> <view class="tn-padding-bottom-lg"></view>
</view> </view>
@@ -97,6 +102,10 @@
} }
}, },
methods: { methods: {
say(msg){
this.$tn.message.toast(msg)
},
} }
} }
</script> </script>

View File

@@ -1,29 +1,22 @@
<template> <template>
<button <button class="tn-btn-class tn-btn" :class="[
class="tn-btn-class tn-btn"
:class="[
buttonClass, buttonClass,
backgroundColorClass, backgroundColorClass,
fontColorClass fontColorClass
]" ]" :style="[buttonStyle]" hover-class="tn-hover" :loading="loading" :disabled="disabled" :form-type="formType"
:style="[buttonStyle]" :open-type="openType" @getuserinfo="handleGetUserInfo" @getphonenumber="handleGetPhoneNumber"
hover-class="tn-hover" @contact="handleContact" @error="handleError" @tap="handleClick">
:loading="loading"
:disabled="disabled"
:form-type="formType"
:open-type="openType"
@getuserinfo="handleGetUserInfo"
@getphonenumber="handleGetPhoneNumber"
@contact="handleContact"
@error="handleError"
@tap="handleClick"
>
<slot></slot> <slot></slot>
</button> </button>
</template> </template>
<script> <script>
import componentsColorMixin from '../../libs/mixin/components_color.js' import componentsColorMixin from '../../libs/mixin/components_color.js'
import {
debounceFun,
throttleFun
} from '../../libs/function/applyEven.js'
let spanTime = 200;
export default { export default {
mixins: [componentsColorMixin], mixins: [componentsColorMixin],
name: "tn-button", name: "tn-button",
@@ -113,6 +106,16 @@
blockRepeatClick: { blockRepeatClick: {
type: Boolean, type: Boolean,
default: false default: false
},
//场景如果开启blockRepeatClick这里无效none 不开启防抖节流模式debounce :防抖模式 throttle节流模式
scene:{
type: String,
default: 'none'
},
// 防抖节流间隔时间(毫秒)
blockTime:{
type: Number,
default: 200
} }
}, },
computed: { computed: {
@@ -162,7 +165,7 @@
// 按钮的样式 // 按钮的样式
buttonStyle() { buttonStyle() {
let style = {} let style = {}
switch(this.size) { switch (this.size) {
case 'sm': case 'sm':
style.padding = '0 20rpx' style.padding = '0 20rpx'
style.fontSize = '22rpx' style.fontSize = '22rpx'
@@ -173,7 +176,7 @@
style.fontSize = '32rpx' style.fontSize = '32rpx'
style.height = this.height || '80rpx' style.height = this.height || '80rpx'
break break
default : default:
style.padding = '0 30rpx' style.padding = '0 30rpx'
style.fontSize = '28rpx' style.fontSize = '28rpx'
style.height = this.height || '64rpx' style.height = this.height || '64rpx'
@@ -212,7 +215,8 @@
if (this.shadow && !this.backgroundColorClass) { if (this.shadow && !this.backgroundColorClass) {
if (this.backgroundColorStyle.indexOf('#') != -1) { if (this.backgroundColorStyle.indexOf('#') != -1) {
style.boxShadow = `6rpx 6rpx 8rpx ${(this.backgroundColorStyle || '#000000')}10` style.boxShadow = `6rpx 6rpx 8rpx ${(this.backgroundColorStyle || '#000000')}10`
} else if (this.backgroundColorStyle.indexOf('rgb') != -1 || this.backgroundColorStyle.indexOf('rgba') != -1 || !this.backgroundColorStyle) { } else if (this.backgroundColorStyle.indexOf('rgb') != -1 || this.backgroundColorStyle.indexOf(
'rgba') != -1 || !this.backgroundColorStyle) {
style.boxShadow = `6rpx 6rpx 8rpx ${(this.backgroundColorStyle || 'rgba(0, 0, 0, 0.1)')}` style.boxShadow = `6rpx 6rpx 8rpx ${(this.backgroundColorStyle || 'rgba(0, 0, 0, 0.1)')}`
} }
@@ -223,28 +227,43 @@
}, },
data() { data() {
return { return {
// 上次点击的时间
clickTime: 0,
// 两次点击防抖的间隔时间
clickIntervalTime: 200
} }
}, },
watch:{
//支持动态修改时间,但是这里是没有做撤销上一次的方法,毕竟这种场景非常少
//这里只是防止用户使用时复用了组件,有场景时长要求二次变动,而做的优化
blockTime:{
handler(newVal,oldVal){
this.initScene();
}
},
},
mounted() {
this.initScene()
},
methods: { methods: {
// 按钮点击事件 initScene(){
handleClick() { // 动态传入blockTime需要重新初始化,参数
if (this.disabled) { //防抖模式
return this.debounceClick=debounceFun(function() {
} this.emitClick();
if (this.blockRepeatClick) { }, this.blockTime);
const nowTime = new Date().getTime() //节流模式
if (nowTime - this.clickTime <= this.clickIntervalTime) { this.throttleClick=throttleFun(function() {
return this.emitClick();
} }, this.blockTime);
this.clickTime = nowTime },
setTimeout(() => { //防抖模式
this.clickTime = 0 debounceClick:debounceFun(function() {
}, this.clickIntervalTime) this.emitClick();
} }, spanTime),
//节流模式
throttleClick:throttleFun(function() {
this.emitClick();
}, spanTime),
emitClick() {
//触发事件
this.$emit('click', { this.$emit('click', {
index: Number(this.index) index: Number(this.index)
}) })
@@ -253,16 +272,45 @@
index: Number(this.index) index: Number(this.index)
}) })
}, },
handleGetUserInfo({ detail = {} } = {}) { // 按钮点击事件
handleClick() {
if (this.disabled) {
return
}
//兼容旧的
if (this.blockRepeatClick) {
this.throttleClick();
return;
}
//普通模式,触发多少次就回调多少次
if(this.scene === 'none'){
this.emitClick();
}else if(this.scene == 'debounce'){
//防抖模式
this.debounceClick();
}else{
//节流模式
this.throttleClick();
}
},
handleGetUserInfo({
detail = {}
} = {}) {
this.$emit('getuserinfo', detail); this.$emit('getuserinfo', detail);
}, },
handleContact({ detail = {} } = {}) { handleContact({
detail = {}
} = {}) {
this.$emit('contact', detail); this.$emit('contact', detail);
}, },
handleGetPhoneNumber({ detail = {} } = {}) { handleGetPhoneNumber({
detail = {}
} = {}) {
this.$emit('getphonenumber', detail); this.$emit('getphonenumber', detail);
}, },
handleError({ detail = {} } = {}) { handleError({
detail = {}
} = {}) {
this.$emit('error', detail); this.$emit('error', detail);
}, },
@@ -272,7 +320,6 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.tn-btn { .tn-btn {
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@@ -298,5 +345,4 @@
} }
} }
} }
</style> </style>

View File

@@ -0,0 +1,28 @@
//防抖
export function debounceFun(func, delay=500) {
//定时器
let timer;
return function(...args) {
// 清除之前设置的定时器
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
//节流
export function throttleFun(func, delay=500) {
//定时器
let timer = null;
return function(...args) {
if(!timer){
timer = setTimeout(() => {
//执行前清空
timer = null;
console.log("执行了")
func.apply(this, args);
}, delay);
}
};
}