Loading...

vue2 自定义指令 实现全屏 、对话框拖拽

模块下载

用于全屏

npm i screenfull@5.1.0 -S 

新建文件

新建directives.js文件,复制下面代码

import Vue from "vue";  // 全屏 import screenfull from "screenfull"; Vue.directive("screenfull", {   bind(el, binding) {     if (binding.modifiers.icon) {       if (el.hasIcon) return;       // 创建全屏图标       const iconElement = document.createElement("i");       iconElement.setAttribute("class", "el-icon-full-screen");       iconElement.setAttribute("style", "margin-left:5px");       el.appendChild(iconElement);       el.hasIcon = true;     }     el.style.cursor = el.style.cursor || "pointer";     // 监听点击全屏事件     el.addEventListener("click", () => {       if (!screenfull.isEnabled) {         alert("浏览器不支持全屏");         return;       }       screenfull.toggle();     });   }, });  // Dialog对话框拖拽 Vue.directive("drag", {   bind(el, binding, vnode) {     const dialogHeaderEl = el.querySelector(".el-dialog__header");     const dragDom = el.querySelector(".el-dialog");     dialogHeaderEl.style.cssText += ";cursor:move;";     dragDom.style.cssText += ";top:0px;";      // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);     const getStyle = (function () {       if (window.document.currentStyle) {         return (dom, attr) => dom.currentStyle[attr];       } else {         return (dom, attr) => getComputedStyle(dom, false)[attr];       }     })();      dialogHeaderEl.onmousedown = (e) => {       // 鼠标按下,计算当前元素距离可视区的距离       const disX = e.clientX - dialogHeaderEl.offsetLeft;       const disY = e.clientY - dialogHeaderEl.offsetTop;        const dragDomWidth = dragDom.offsetWidth;       const dragDomHeight = dragDom.offsetHeight;        const screenWidth = document.body.clientWidth;       const screenHeight = document.body.clientHeight;        const minDragDomLeft = dragDom.offsetLeft;       const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;        const minDragDomTop = dragDom.offsetTop;       const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight;        // 获取到的值带px 正则匹配替换       let styL = getStyle(dragDom, "left");       let styT = getStyle(dragDom, "top");        if (styL.includes("%")) {         styL = +document.body.clientWidth * (+styL.replace(/%/g, "") / 100);         styT = +document.body.clientHeight * (+styT.replace(/%/g, "") / 100);       } else {         styL = +styL.replace(/\px/g, "");         styT = +styT.replace(/\px/g, "");       }        document.onmousemove = function (e) {         // 通过事件委托,计算移动的距离         let left = e.clientX - disX;         let top = e.clientY - disY;          // 边界处理         if (-left > minDragDomLeft) {           left = -minDragDomLeft;         } else if (left > maxDragDomLeft) {           left = maxDragDomLeft;         }          if (-top > minDragDomTop) {           top = -minDragDomTop;         } else if (top > maxDragDomTop) {           top = maxDragDomTop;         }          // 移动当前元素         dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;          // emit onDrag event         vnode.child.$emit("dragDialog");       };        document.onmouseup = function () {         document.onmousemove = null;         document.onmouseup = null;       };     };   }, });  

全局引入

main.js中引入文件import "@/src/utils/directives";

使用

全屏

加上v-screenfull
示例:

<i class="el-icon-full-screen" v-screenfull></i> 

dialog对话框拖拽

加上v-drag
示例:

 <el-dialog    v-drag    title="标题"    :visible.sync="dialogVisible"    width="30%"    :before-close="handleClose"  >  <el-dialog>