vue自定义指令directive的全局注册和局部注册
先看最基础对比:
局部注册:在一个要使用的vue组件内:
directives: {
drag: { ...},
focus: ...
directives: { drag: { bind: (el, binding) => { console.log(el); console.log(binding.value); //绑定默认样式 el.style.zIndex = 9; // el.style.backgroundColor = "rgba(189,220,251,0.88)"; el.style.radius = "4px"; //如果为编辑状态 if (binding.value || binding.value === undefined) { //定义该元素的 top left width height let x, y, w, h; //鼠标的起始和结束坐标 let cx_start, cy_start, cx_end, cy_end; //判断鼠标样式 el.onmousemove = (e) => { //获取鼠标当前位置 let cx_now = e.clientX; let cy_now = e.clientY; //获取div右下角相对浏览器的位置 let { top: el_top, left: el_left, width: el_width, height: el_height, } = el.getBoundingClientRect(); let el_bottom_height = el_top + el_height; let el_right_width = el_left + el_width; //判断鼠标是否在div下边界 let mouse_in_bottom = cy_now <= el_bottom_height + 5 && cy_now >= el_bottom_height - 5; //判断鼠标是否在div右边界 let mouse_in_right = cx_now <= el_right_width + 5 && cx_now >= el_right_width - 5; if (mouse_in_bottom && mouse_in_right) { el.style.cursor = "se-resize"; } else if (mouse_in_right) { el.style.cursor = "e-resize"; } else if (mouse_in_bottom) { el.style.cursor = "s-resize"; } else { el.style.cursor = "move"; } }; el.onmousedown = (e) => { let mouse = el.style.cursor; //更改默认样式 // el.style.backgroundColor = "rgba(189,220,251,0.88)"; el.style.zIndex = 99; //对象解构赋值 let { left: el_x, top: el_y, width: el_w, height: el_h, } = window.getComputedStyle(el); x = el_x; y = el_y; w = el_w; h = el_h; console.log(x, y, w, h); // 坐标 cx_start = e.clientX; cy_start = e.clientY; //绑定移动事件 document.onmousemove = (e) => { cx_end = e.clientX; cy_end = e.clientY; //默认左下方向配置 let x_move = cx_end - cx_start; let y_move = cy_end - cy_start; let direct = ["width", "height"]; let pos = [w, h]; let move = [x_move, y_move]; let limit = 50; //判断鼠标的类型进行对应的操作 switch (mouse) { case "e-resize": direct = ["width"]; pos = [w]; move = [x_move]; break; case "s-resize": direct = ["height"]; pos = [h]; move = [y_move]; break; case "move": direct = ["left", "top"]; pos = [x, y]; limit = 0; break; } handle_div(direct, pos, move, limit); }; //取消移动事件 document.onmouseup = (e) => { console.log(e); //还原默认样式 -拖拽后 el.style.zIndex = 9; // el.style.backgroundColor = "rgba(189,220,251,0.88)"; document.onmousemove = null; }; /** * 操作DOM位置和大小方法 * @param direct 方向 * @param pos 尺寸/坐标 * @param move 拖动距离 * @param limit 限定范围 */ function handle_div(direct, pos, move, limit) { for (let i = 0; i < direct.length; i++) { let val = parseInt(pos[i]) + move[i]; val = val <= limit ? limit : val; el.style[direct[i]] = val + "px"; } } }; } else { el.style.cursor = "default"; //移除点击事件 el.onmousedown = null; el.onmousemove = null; } }, }, },
如果多个组件都需要使用drag,那就需要提炼到全局注册上了,如果有关联到样式,样式也需要提炼
1:首先新建一个指令js文件 drag.js
import Vue from 'vue' export const drag = Vue.directive('drag',{ bind: (el, binding) => { console.log(el); console.log(binding.value); //绑定默认样式 el.style.zIndex = 9; // el.style.backgroundColor = "rgba(189,220,251,0.88)"; el.style.radius = "4px"; //如果为编辑状态 if (binding.value || binding.value === undefined) { //定义该元素的 top left width height let x, y, w, h; //鼠标的起始和结束坐标 let cx_start, cy_start, cx_end, cy_end; //判断鼠标样式 el.onmousemove = (e) => { //获取鼠标当前位置 let cx_now = e.clientX; let cy_now = e.clientY; //获取div右下角相对浏览器的位置 let { top: el_top, left: el_left, width: el_width, height: el_height, } = el.getBoundingClientRect(); let el_bottom_height = el_top + el_height; let el_right_width = el_left + el_width; //判断鼠标是否在div下边界 let mouse_in_bottom = cy_now <= el_bottom_height + 5 && cy_now >= el_bottom_height - 5; //判断鼠标是否在div右边界 let mouse_in_right = cx_now <= el_right_width + 5 && cx_now >= el_right_width - 5; if (mouse_in_bottom && mouse_in_right) { el.style.cursor = "se-resize"; } else if (mouse_in_right) { el.style.cursor = "e-resize"; } else if (mouse_in_bottom) { el.style.cursor = "s-resize"; } else { el.style.cursor = "move"; } }; el.onmousedown = (e) => { let mouse = el.style.cursor; //更改默认样式 // el.style.backgroundColor = "rgba(189,220,251,0.88)"; el.style.zIndex = 99; //对象解构赋值 let { left: el_x, top: el_y, width: el_w, height: el_h, } = window.getComputedStyle(el); x = el_x; y = el_y; w = el_w; h = el_h; console.log(x, y, w, h); // 坐标 cx_start = e.clientX; cy_start = e.clientY; //绑定移动事件 document.onmousemove = (e) => { cx_end = e.clientX; cy_end = e.clientY; //默认左下方向配置 let x_move = cx_end - cx_start; let y_move = cy_end - cy_start; let direct = ["width", "height"]; let pos = [w, h]; let move = [x_move, y_move]; let limit = 50; //判断鼠标的类型进行对应的操作 switch (mouse) { case "e-resize": direct = ["width"]; pos = [w]; move = [x_move]; break; case "s-resize": direct = ["height"]; pos = [h]; move = [y_move]; break; case "move": direct = ["left", "top"]; pos = [x, y]; limit = 0; break; } handle_div(direct, pos, move, limit); }; //取消移动事件 document.onmouseup = (e) => { console.log(e); //还原默认样式 -拖拽后 el.style.zIndex = 9; // el.style.backgroundColor = "rgba(189,220,251,0.88)"; document.onmousemove = null; }; /** * 操作DOM位置和大小方法 * @param direct 方向 * @param pos 尺寸/坐标 * @param move 拖动距离 * @param limit 限定范围 */ function handle_div(direct, pos, move, limit) { for (let i = 0; i < direct.length; i++) { let val = parseInt(pos[i]) + move[i]; val = val <= limit ? limit : val; el.style[direct[i]] = val + "px"; } } }; } else { el.style.cursor = "default"; //移除点击事件 el.onmousedown = null; el.onmousemove = null; } }, })
export const drag Vue.directive('drag',{...}) 当然也可以直接放在man.js内直接写成:Vue.directive('drag',{...})
2:man.js内
import './components/gongju/drag'
import '../public/style/common.css'
3:新建需要用到的公用样式:
.drag { width: 600px; /* height: 30px; */ position: absolute; top: 580px; left: 500px; padding: 10px; border-radius: 2px; padding: 4px; position: fixed; }
4:在想要使用的组件直接使用即可:
比如在gate组件内:
<el-card class="drag" v-drag> <div :id="idgatega" :style="{ width: this.width, height: this.height }" ></div> </el-card>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!