This commit is contained in:
hezhidong
2025-05-16 08:55:13 +08:00
parent e62c3fce70
commit 839703dc1a
66 changed files with 5029 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
import draggable from "./modules/draggable";
import copy from "./modules/copy";
import debounce from "./modules/debounce";
import longPress from "./modules/longPress";
import throttle from "./modules/throttle";
const directivesList = {
draggable,
copy,
debounce,
longPress,
throttle
};
const directives = {
install: function (app) {
Object.keys(directivesList).forEach((key) => {
// 注册所有自定义指令
app.directive(key, directivesList[key]);
});
},
};
export default directives;
+58
View File
@@ -0,0 +1,58 @@
/*
需求:实现一个复制指定。复制指定内容至剪贴板
1.动态创建 textarea 标签,并设置 readOnly 属性及移出可视区域
2.将要复制的值赋给 textarea 标签的 value 属性,并插入到 body
3.选中值 textarea 并复制
4.将 body 中插入的 textarea 移除
5.在第一次调用时绑定事件,在解绑时移除事件
*/
import { ElMessage } from "element-plus";
export const copy = {
mounted: function (el, { value }) {
console.log(arguments);
el.$value = value;
el.onclick = () => {
if (!el.$value) {
// 值为空的时候,给出提示。可根据项目UI仔细设计
ElMessage({
type: "error",
message: "无复制内容",
});
return;
}
// 动态创建 textarea 标签
const textarea = document.createElement("input");
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = "readonly";
textarea.style.position = "absolute";
textarea.style.left = "-9999px";
// 将要 copy 的值赋给 textarea 标签的 value 属性
textarea.value = el.$value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
const result = document.execCommand("Copy");
if (result) {
ElMessage({
type: "success",
message: "复制成功",
});
}
document.body.removeChild(textarea);
};
// 绑定点击事件,就是所谓的一键 copy 啦
el.addEventListener("click", el.handler);
},
// 当传进来的值更新的时候触发
beforeUpdate(el, { value }) {
el.$value = value;
},
// 指令与元素解绑的时候,移除事件绑定
unmounted(el) {
el.removeEventListener("click", el.handler);
},
};
export default copy;
+28
View File
@@ -0,0 +1,28 @@
/**
* v-debounce
* 按钮防抖指令,可自行扩展至input
* 接收参数:function类型
*/
const debounce = {
mounted(el, binding) {
if (typeof binding.value != "function") {
console.log("callback must be a function");
}
let timer = null;
el.__handleClick__ = function () {
// if (timer) clearInterval(timer);
//
timer && clearTimeout(timer)
timer = setTimeout(() => {
binding.value();
}, 3000);
};
el.addEventListener("click", el.__handleClick__);
},
beforeUnmount(el) {
el.removeEventListener("click", el.__handleClick__);
},
};
export default debounce;
+47
View File
@@ -0,0 +1,47 @@
/*
需求:实现一个拖拽指令,可在父元素区域任意拖拽元素。
思路:
1、设置需要拖拽的元素为absolute,其父元素为relative。
2、鼠标按下(onmousedown)时记录目标元素当前的 left 和 top 值。
3、鼠标移动(onmousemove)时计算每次移动的横向距离和纵向距离的变化值,并改变元素的 left 和 top 值
4、鼠标松开(onmouseup)时完成一次拖拽
使用:在 Dom 上加上 v-draggable 即可
<div class="dialog-model" v-draggable></div>
*/
const draggable = {
mounted: function (el) {
console.log(el)
el.style.cursor = "move";
el.style.position = "absolute";
el.onmousedown = function (e) {
let disX = e.pageX - el.offsetLeft;
let disY = e.pageY - el.offsetTop;
document.onmousemove = function (e) {
let x = e.pageX - disX;
let y = e.pageY - disY;
console.log(el.parentNode.offsetWidth)
let maxX = el.parentNode.offsetWidth - el.offsetWidth;
let maxY = el.parentNode.offsetHeight - el.offsetHeight;
if (x < 0) {
x = 0;
} else if (x > maxX) {
x = maxX;
}
if (y < 0) {
y = 0;
} else if (y > maxY) {
y = maxY;
}
el.style.left = x + "px";
el.style.top = y + "px";
};
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
};
};
}
};
export default draggable;
+44
View File
@@ -0,0 +1,44 @@
const longPress = {
mounted(el, binding) {
if (typeof binding.value != "function") {
console.log("callback must be a function");
}
let pressTimer = null;
let start = (e) => {
if (e.type === "click" && e.button !== 0) {
return;
}
if (pressTimer === null) {
pressTimer = setTimeout(() => {
// 执行函数
handler();
}, 2000);
}
};
// 取消计时器
let cancel = () => {
// 检查计时器是否有值
if (pressTimer !== null) {
clearTimeout(pressTimer);
pressTimer = null;
}
};
// 运行函数
const handler = (e) => {
// 执行传递给指令的方法
binding.value(e);
console.log(e);
};
// 添加事件监听器
el.addEventListener("mousedown", start);
el.addEventListener("touchstart", start);
el.addEventListener("click", start);
// 取消计时器
el.addEventListener("click", cancel);
el.addEventListener("mouseout", cancel);
el.addEventListener("touchend", cancel);
el.addEventListener("touchcancel", cancel);
},
};
export default longPress;
+30
View File
@@ -0,0 +1,30 @@
/**
* 一段时间内控制请求的频率
* 上一次时间触发的时间和这次触发的时间相减 传入节流的时间
*
*
* 应用场景:scroll加载的时候 和input框输入的情况
*/
const throttle = {
mounted(el, binding) {
if (typeof binding.value != "function") {
console.log("callback must be a function");
}
let lastTime = 0
let newtimer = +new Date(); //拿到当前的时间
el.__handleClick__ = function () {
if (newtimer - lastTime > 3000) {
binding.value()
lastTime = newtimer
}
};
el.addEventListener("click", el.__handleClick__);
},
beforeUnmount(el) {
el.removeEventListener("click", el.__handleClick__);
},
}
export default throttle