Explorar o código

Merge branch 'main' of github.com:xiaoxian521/vue-pure-admin

xiaoxian521 %!s(int64=3) %!d(string=hai) anos
pai
achega
14619588d4

+ 3 - 2
locales/en.yaml

@@ -74,5 +74,6 @@ menus:
   hsAntTabs: Imitate Antdv Tabs
   hsAntAnchor: Imitate Antdv Anchor
   hsAntTreeSelect: Imitate Antdv TreeSelector
-  list: List Page
-  listCard: Card List Page
+  hsList: List Page
+  hsListCard: Card List Page
+  hsDebounce: Debounce & Throttle

+ 3 - 2
locales/zh-CN.yaml

@@ -74,5 +74,6 @@ menus:
   hsAntTabs: 仿antdv标签页
   hsAntAnchor: 仿antdv锚点
   hsAntTreeSelect: 仿antdv树型选择器
-  list: 列表页
-  listCard: 卡片列表页
+  hsList: 列表页
+  hsListCard: 卡片列表页
+  hsDebounce: 防抖节流

+ 9 - 0
src/router/modules/able.ts

@@ -92,6 +92,15 @@ const ableRouter = {
         title: $t("menus.hsAntTreeSelect"),
         i18n: true
       }
+    },
+    {
+      path: "/able/debounce",
+      name: "reDebounce",
+      component: () => import("/@/views/able/debounce.vue"),
+      meta: {
+        title: $t("menus.hsDebounce"),
+        i18n: true
+      }
     }
   ]
 };

+ 2 - 2
src/router/modules/list.ts

@@ -7,7 +7,7 @@ const ableRouter = {
   redirect: "/list/card",
   meta: {
     icon: "list-check",
-    title: $t("menus.list"),
+    title: $t("menus.hsList"),
     i18n: true,
     rank: 12
   },
@@ -18,7 +18,7 @@ const ableRouter = {
       component: () => import("/@/views/list/card/index.vue"),
       meta: {
         icon: "card",
-        title: $t("menus.listCard"),
+        title: $t("menus.hsListCard"),
         i18n: true,
         showParent: true
       }

+ 31 - 4
src/utils/debounce/index.ts

@@ -1,12 +1,39 @@
+import { unref } from "vue";
+import type { Ref } from "vue";
+
+type FunctionArgs<Args extends any[] = any[], Return = void> = (
+  ...args: Args
+) => Return;
+
+type MaybeRef<T> = T | Ref<T>;
+
 // 延迟函数
 export const delay = (timeout: number) =>
   new Promise(resolve => setTimeout(resolve, timeout));
 
-// 防抖函数
-export const debounce = (fn: () => Fn, timeout: number) => {
+/**
+ * 防抖函数
+ * @param fn 函数
+ * @param timeout 延迟时间
+ * @param immediate 是否立即执行
+ * @returns
+ */
+export const debounce = <T extends FunctionArgs>(
+  fn: T,
+  timeout: MaybeRef<number> = 200,
+  immediate = false
+) => {
   let timmer: TimeoutHandle;
+  const wait = unref(timeout);
   return () => {
-    timmer ? clearTimeout(timmer) : null;
-    timmer = setTimeout(fn, timeout);
+    timmer && clearTimeout(timmer);
+    if (immediate) {
+      if (!timmer) {
+        fn();
+      }
+      timmer = setTimeout(() => (timmer = null), wait);
+    } else {
+      timmer = setTimeout(fn, wait);
+    }
   };
 };

+ 52 - 0
src/views/able/debounce.vue

@@ -0,0 +1,52 @@
+<script setup lang="ts">
+import { ElMessage } from "element-plus";
+import { debounce } from "/@/utils/debounce";
+import { useDebounceFn, useThrottleFn } from "@vueuse/core";
+
+const handle = () => {
+  ElMessage({
+    message: "恭喜你,这是一条成功消息",
+    type: "success"
+  });
+};
+
+const immediateDebounce = debounce(handle, 1000, true);
+
+const debounceClick = useDebounceFn(handle, 1000);
+
+const throttleClick = useThrottleFn(handle, 1000, false);
+</script>
+
+<template>
+  <div>
+    <el-card class="mb-5">
+      <template #header>
+        <div>防抖:debounce</div>
+      </template>
+      <div class="mb-5">
+        所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n
+        秒内又触发了事件,则会重新计算函数执行时间。
+      </div>
+      <el-button @click="immediateDebounce"
+        >连续点击我,只会执行最后一次点击事件,立即执行</el-button
+      >
+      <el-button @click="debounceClick"
+        >连续点击我,只会执行最后一次点击事件,延后执行</el-button
+      >
+    </el-card>
+    <el-card>
+      <template #header>
+        <div>节流:throttle</div>
+      </template>
+      <div class="mb-5">
+        所谓节流,就是指连续触发事件但是在 n
+        秒中只执行一次函数。节流会稀释函数的执行频率。
+      </div>
+      <el-button @click="throttleClick"
+        >连续点击我,每一秒只会执行一次点击事件</el-button
+      >
+    </el-card>
+  </div>
+</template>
+
+<style scoped></style>

+ 1 - 5
src/views/tabs/index.vue

@@ -55,11 +55,7 @@ function onCloseTags() {
 <template>
   <el-card>
     <template #header>
-      <div class="card-header">
-        <span class="font-medium"
-          >标签页复用,超出限制自动关闭(使用场景: 动态路由)</span
-        >
-      </div>
+      <div>标签页复用,超出限制自动关闭(使用场景: 动态路由)</div>
     </template>
     <el-button v-for="index in 6" :key="index" @click="toDetail(index)">
       打开{{ index }}详情页