先看最基礎對比:
局部注冊:在一個要使用的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>