UNPKG

wdy_custom_hooks

Version:

one custom hooks of vue3

337 lines (284 loc) 8.43 kB
## 基于 Vue3 的常用自定义指令钩子 - 安装指令:`pnpm i wdy_custom_hooks` - 使用方式,全局注册(在项目 main.ts 或者 main.js 中引入): ```ts import { createApp } from "vue"; import App from "./app.vue"; // 引入自定义指令 import { useResize, useFocus } from "wdy_custom_hooks"; const app = createApp(App); // 全局注册指令 app.use(useResize); app.use(useFocus); app.mount("#app"); ``` - 目前可供使用的指令以及使用 Demo:<br> [1. v-focus:自动焦点](#v-focus自动焦点)<br> [2. v-resize:监听元素大小的变化](#v-resize监听元素大小的变化)<br> [3. v-copy:复制文本](#v-copy复制文本)<br> [4. v-scrollLoad:滚动加载更多](#v-scrollload滚动加载更多)<br> [5. v-imgLazy:图片懒加载](#v-imgLazy图片懒加载)<br> [6. v-longPress:绑定长按事件](#v-longPress绑定长按事件)<br> [7. v-waterMarker:页面水印](#v-waterMarker页面水印)<br> [8. v-outsideClick:点击元素外部事件](#v-outsideclick点击元素外部事件)<br> [9. v-debounce:防抖指令](#v-debounce防抖指令)<br> [10. v-throttle:节流指令](#v-throttle节流指令)<br> [11. v-permission:权限按钮指令](#v-permission权限按钮指令)<br> ### v-focus:自动焦点 ```vue <template> <input v-focus /> </template> ``` ### v-resize:监听元素大小的变化 ```vue <template> <!-- 基本用法,默认200ms触发一次 --> <div v-resize="resizeCallback"></div> <!-- 支持自定义防抖时间 --> <div v-resize:300="resizeCallback"></div> </template> <script setup lang="ts"> // 元素大小的变化回调函数 const resizeCallback = (e) => { console.log("回调触发了:" + e); }; </script> ``` ### v-copy:复制文本 ```vue <template> <button v-copy="copyConfig">点击复制</button> </template> <script setup lang="ts"> import { ref } from "vue"; import { ElMessage } from "element-plus"; const copyConfig = ref({ text: "Hello,World!", // 要复制的文本 // 自定义复制成功的回调,可选,默认console.log("复制成功") success: () => { ElMessage.success("复制成功"); }, // 自定义复制失败的回调,可选,默认console.error("复制失败") error: (err: any) => { ElMessage.error("失败:" + err); }, }); </script> ``` ### v-scrollLoad:滚动加载更多 ```vue <template> <div style="height: 100vh; overflow: auto" v-scrollLoad="scrollConfig"> <ul> <li v-for="item in items" :key="item" style="padding: 30px; font-size: 20px" > {{ item }} </li> </ul> <div v-if="loading" style=" height: 50px; display: flex; justify-content: center; font-size: 20px; " > <el-icon><Loading /></el-icon> </div> </div> </template> <script setup lang="ts"> import { ref } from "vue"; import { Loading } from "@element-plus/icons-vue"; const loading = ref(false); const items = ref<string[]>([ "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", ]); // 指令配置项 const scrollConfig = ref({ distance: 100, // 距离底部的距离,可选,默认举例底部100px触发回调 loadMoreFn: loadMore, // 回调函数 }); // 模拟请求,加载更多数据 async function loadMore() { if (loading.value) return; if (items.value.length >= 30) return; // 假设数据只有30条 loading.value = true; console.log("触发了回调"); // 模拟加载更多数据, 每次加载10条数据; for (let i = 0; i < 10; i++) { items.value.push("Item " + (items.value.length + 1)); } loading.value = false; } </script> ``` ### v-imgLazy:图片懒加载 ```vue <template> <div> <img v-lazyLoad="imgConfig" alt="Image" /> </div> </template> <script setup lang="ts"> import { ref } from "vue"; const imgConfig = ref({ // 真实图片地址 src: "https://q4.itc.cn/images01/20241017/4cf3fe55a9584eb0b2c111f9e0baabfd.jpeg", // 占位图地址,可选,没有默认的占位图 placeholderSrc: "https://img.zcool.cn/community/01efbc5a1e6efda80120908dcb1567.gif", // 加载失败图地址,可选,没有默认的加载失败图 errorSrc: "https://gss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/574e9258d109b3de93ad439cc9bf6c81800a4c37.jpg", }); </script> ``` ### v-longPress:绑定长按事件 ```vue <template> <div> {{ count }} <el-button type="primary" v-longPress="longPressConfig"> 长按我 </el-button> </div> </template> <script setup lang="ts"> import { ref } from "vue"; const count = ref(1); const longPressConfig = ref({ callback: () => { console.log("长按事件触发!"); count.value++; }, // 长按事件触发的回调函数 time: 2000, // 长按事件触发的时间,可选,默认 2000ms }); </script> ``` ### v-waterMarker:页面水印 ```vue <template> <div v-waterMarker="waterMarkerConfig" style="width: 100%; height: 100vh;"> <h1>我的标题</h1> <p>这是页面内容……</p> </div> </template> <script setup lang="ts"> import { ref } from "vue"; const waterMarkerConfig = ref({ text: "某某档案@123456789@qq.com", // 水印内容 font: "16px Microsoft Yahei", // 字体样式,可选,默认 '16px Microsoft Yahei' color: "rgba(0, 0, 0, 0.1)", // 字体颜色,可选,默认 'rgba(0, 0, 0, 0.1)' rotate: -20, // 字体旋转角度,可选, 默认 -20 labelGap: 50, // 水印之间的间距,可选, 默认 50 }); </script> ``` ### v-outsideClick:点击元素外部事件 ```vue <template> <div v-outsideClick="clickOutside" style="position: relative; margin: 30px"> <button @click="visible = true">下拉菜单</button> <div v-if="visible" style=" position: absolute; top: 30px; z-index: 99; background-color: #bfa; width: 150px; height: 200px; padding: 6px 10px; border: 1px solid #d9d9d9; " > <ul> <li>菜单项1</li> <li>菜单项2</li> <li>菜单项3</li> </ul> </div> </div> </template> <script setup lang="ts"> import { ref } from "vue"; const visible = ref(false); const clickOutside = () => { visible.value = false; }; </script> ``` ### v-debounce:防抖指令 ```vue <template> <el-button type="primary" v-debounce:click="debounceConfig" >防抖测试{{ count }}</el-button > </template> <script setup lang="ts"> import { ref } from "vue"; const count = ref(0); const debounceConfig = ref({ callback: () => { // 点击事件触发的回调函数 console.log("点击了按钮"); count.value++; }, delay: 500, // 点击事件触发的时间,可选,默认 300ms }); </script> ``` ### v-throttle:节流指令 ```vue <template> <el-button type="primary" v-debounce:click="debounceConfig" >节流测试{{ count }}</el-button > </template> <script setup lang="ts"> import { ref } from "vue"; const count = ref(0); const throttleConfig = ref({ callback: () => { // 点击事件触发的回调函数 console.log("点击了按钮"); count.value++; }, delay: 500, // 点击事件触发的时间,可选,默认 300ms }); </script> ``` ### v-permission:权限按钮指令 ```vue <template> <div> <button v-permission:sys:user:add="permissions">添加用户</button> <button v-permission:[dynaimcAuth]="permissions">删除角色</button> </div> </template> <script setup> import { ref, onMounted } from "vue"; // 模拟用户权限列表,实际项目中可以从 Vuex 或 Pinia或请求 中获取 const permissions = ref(["sys:user:add", "sys:role:add", "sys:role:delete"]); // 动态按钮权限 const dynaimcAuth = ref("sys:user:delete"); onMounted(() => { setTimeout(() => { dynaimcAuth.value = "sys:role:delete"; // 模拟按钮权限变化 permissions.value = ["sys:role:add", "sys:role:delete"]; // 模拟用户权限列表变化 }, 3000); }); ```