vue3+ts , 按钮防抖和动态禁用按钮

<!--
 * 按钮事件
 *
 * <template>
 *   //  v-model动态控制disabled
 *   <q-button v-model="btnLoading" @click="handleClick">确定</q-button>
 *   <q-button @click="handleClick">确定</q-button>
 * </template>

 * <script setup>
 *  const handleClick = () => {
 *   console.log('按钮被点击了');
 * };
 * </script>
-->

<script lang="ts">
import { defineComponent, ref, computed, PropType, watch } from "vue";

export default defineComponent({
    name: "DebouncedButton",
    props: {
        // 防抖时间(毫秒),用于定时重置按钮
        debounceTime: {
            type: Number as PropType<number>,
            default: 1500, // 默认1.5秒
        },
        // 按钮禁用状态,通过 v-model 传入,默认为 undefined 表示未传入
        modelValue: {
            type: Boolean as PropType<boolean | undefined>,
            default: undefined,
        },
    },
    emits: ["click", "update:modelValue"],
    setup(props, { emit }) {
        // 内部禁用状态控制(当 modelValue 不传值时使用)
        const internalDisabled = ref(false);

        // 根据是否传入 modelValue 来决定按钮禁用状态的计算属性
        const isButtonDisabled = computed(() => props.modelValue || internalDisabled.value);

        // 点击事件处理
        const handleClick = () => {
            if (!isButtonDisabled.value) {
                // 触发外部的点击事件
                emit("click");

                if (props.modelValue !== undefined) {
                    // 如果传入了 modelValue,使用外部控制禁用状态
                    emit("update:modelValue", true);
                } else {
                    // 如果没有传入 modelValue,使用内部控制禁用状态,并设置定时器
                    internalDisabled.value = true;
                    setTimeout(() => {
                        internalDisabled.value = false;
                    }, props.debounceTime);
                }
            }
        };

        // 监听 modelValue 的变化,确保在外部重新启用时也能解除内部禁用
        watch(
            () => props.modelValue,
            (newVal) => {
                if (newVal === false) {
                    internalDisabled.value = false;
                }
            },
        );

        return {
            handleClick,
            isButtonDisabled,
        };
    },
});
</script>

<template>
    <!-- type="primary" -->
    <el-button type="danger" :disabled="isButtonDisabled" @click="handleClick">
        <slot></slot>
    </el-button>
</template>

<style scoped></style>


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容