基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件

这篇具有很好参考价值的文章主要介绍了基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源码下载

改组件继承el-dialog组件百分之95属性,可直接对<el-dialog>进行替换。在项目中我的命名为:

SkDialog。废话不多说,直接上代码:

vue代码:搞成组件,路径随意,推荐统一放在组件目录下

el–dialog如何放大缩小,element,ui,vue.js,前端

<!--
@author: kzy;
 -->
<template>
  <el-dialog ref="skDialog"
             custom-class="dialogHeightFull skDialog"
             :title="title"
             :fullscreen="fullFlag"
             :visible.sync="dialogVisible"
             :append-to-body="appendToBody"
             :lock-scroll="lockScroll"
             :modal-append-to-body="modalAppendToBody"
             :close-on-click-modal="closeOnClickModal"
             :close-on-press-escape="closeOnPressEscape"
             :show-close="false"
             :before-close="beforeClose"
             :center="center"
             :destroy-on-close="destroyOnClose"
             :width="width"
             :top="top"
             v-if="dialogVisible"
             v-sk-dialog-drag
             @closed="closeSkDialog">
    <div slot="title" class="skDialog-header">
      <div class="skDialog-title"><span>{{title}}</span></div>
      <div class="skDialog-icon">
        <i :class="fullFlag? 'el-icon-copy-document' : 'el-icon-full-screen' " @click="IsFullscreen"></i>
        <i class="el-icon-close" @click="closeSkDialog"></i>
      </div>
    </div>
    <div class="el-dialog__body"  v-if="rendered"><slot :style="{height:height}"></slot></div>
    <div class="el-dialog__footer" v-if="$slots.footer">
      <slot name="footer"></slot>
    </div>
    <div class="resize"></div>
  </el-dialog>
</template>

<script>
  export default {
    name: 'SkDialog',
    props: {
      visible: {
        type: Boolean,
        default: false
      },
      titleVisible: {
        type: Boolean,
        default: true
      },
      width: {
        type: String,
        default: '50%'
      },
      height: {
        type: String,
        default: '100%'
      },
      top: {
        type: String,
        default: '30px'
      },
      title: {
        type: String,
        default: ''
      },
      isfullscreen: {
        type: Boolean,
        default: false // 默认全屏
      },

      modal: {
        type: Boolean,
        default: true
      },

      modalAppendToBody: {
        type: Boolean,
        default: true
      },

      appendToBody: {
        type: Boolean,
        default: true
      },

      lockScroll: {
        type: Boolean,
        default: true
      },

      closeOnClickModal: {
        type: Boolean,
        default: false
      },

      closeOnPressEscape: {
        type: Boolean,
        default: false
      },

      showClose: {
        type: Boolean,
        default: true
      },

      customClass: {
        type: String,
        default: ''
      },

      beforeClose: Function,
      center: {
        type: Boolean,
        default: false
      },

      destroyOnClose: Boolean
    },
    data() {
      return {
        full: false, // 全屏
      }
    },
    computed: {
      fullFlag: {
        get: function() {
          return this.full ?? this.isfullscreen;
        },
        set: function(n) {
          return this.full
        }
      },
      dialogVisible:{ //重新设置一个变量,接收父级传递的参数,引用页面需要使用语法糖,才能使用this.$emit('update:visible', false)对父组件值进行更新
        get:function(){
          return this.visible
        },
        set :function(value){
          this.$emit('update:visible', false)
        }
      },
      rendered:{ //重新设置一个变量,接收父级传递的参数
        get:function(){
          return this.visible
        },
      }
    },
    mounted() {
    },
    methods: {
      // 全屏 切换
      IsFullscreen() {
        let dialogDom = document.querySelector(".skDialog");
        if (this.isfullscreen == true) {
          this.full = this.full === null ? false : !this.full
        } else {
          this.full = this.full === null ? true : !this.full
          dialogDom.style.top =`0px`;
          dialogDom.style.left =`auto`;
        }
        // 传过来的全屏钩子函数
        this.$emit('maxFun')
      },
      // 关闭
      closeSkDialog() {
        this.full = null
        this.$emit('update:visible', false)
        // 传过来的关闭钩子函数
        this.$emit('closeFun')
      }
    },
    watch:{
    },
    created() {
      this.full = this.isfullscreen
    },
  }
</script>

<style scoped="scoped">
  >>>.el-dialog__header {
    background-color: #f2f2f2;
    /* height: 48px; */
    padding: 10px 20px 10px;
  }

  .skDialog-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }

  .skDialog .skDialog-icon i {
    display: inline-block;
    height: 28px;
    width: 28px;
    line-height: 24px;
    text-align: center;
    border-radius: 50%;
    cursor: pointer;
    font-size: 22px;
  }

  .skDialog .skDialog-icon i:hover {
    background-color: #ddd;
  }

  .skDialog .skDialog-icon i::before {
    font-size: 80%;
  }

  >>>.skDialog.dialogHeightFull.el-dialog {
    margin-bottom: 0;
    /*overflow-y: hidden;*/
  }

  .el-dialog__wrapper{
    /*overflow: hidden!important;*/
  }
  .resize{
    position: absolute;
    right: 0;
    bottom: 0;
    content: '';
    width: 10px;
    height: 10px;
    cursor: se-resize;
  }
</style>

拖动及缩放操作js代码:

/**
 @author: kzy;
 */
import Vue from 'vue'
Vue.directive("SkDialogDrag", {
  bind(el, binding, vnode, oldVnode) {
    const windowW = document.body.clientWidth;
    const windowH = document.body.clientHeight
    //设置弹框可拉伸最小宽高
    let minWidth = 400;
    let minHeight = 300;
    const dialogHeaderEl = el.querySelector(".el-dialog__header");
    //弹窗
    const dragDom = el.querySelector(".el-dialog");
    //头部加上可拖动cursor
    dialogHeaderEl.style.cursor = "move";

    // 获取style属性
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);

    let moveDown = e => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;

      // 获取到的值带px 正则匹配替换
      let styL, styT, styMT;
      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes("%")) {
        styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, "") / 100);
        styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, "") / 100);
      } else {
        styL = +sty.left.replace(/\px/g, "");
        styT = +sty.top.replace(/\px/g, "");
        styMT = +sty.marginTop.replace(/\px/g, "")
      }

      document.onmousemove = function (e) {
        const titleH = dialogHeaderEl.offsetHeight;

        // 通过事件委托,计算移动的距离
        let l = e.clientX - disX;
        let t = e.clientY - disY;

        // 移动边界处理
        if (t < 0 && (t + styMT + styT) <= 0 || t < 0 && (styMT + styT) <= 0) {
          t = -(styMT + styT);
        } else if (t > 0 && t > (document.body.clientHeight - styMT - styT - titleH)) {
          t = document.body.clientHeight - styMT - styT - titleH;
        }

        // 移动当前元素
        dragDom.style.left = `${l + styL}px`;
        dragDom.style.top = `${t + styT}px`;

      };

      document.onmouseup = function (e) {
        document.onmousemove = null;
        document.onmouseup = null;
      };

    };

    dialogHeaderEl.onmousedown = moveDown;

    dragDom.onmousemove = function (e) {
      const dialogBODY = el.querySelector(".el-dialog__body");
      const resizeDom= el.querySelector(".resize");
      const titleH = dialogHeaderEl.offsetHeight;
      dragDom.onmousedown = e => {
        const clientX = e.clientX;
        const clientY = e.clientY;
        let elW = dragDom.clientWidth;
        let elH = dragDom.clientHeight;
        let EloffsetLeft = dragDom.offsetLeft;
        let EloffsetTop = dragDom.offsetTop;
        let ELscrollTop = el.scrollTop;
        let resizeW = resizeDom.clientWidth, resizeH = resizeDom.clientHeight;

        //判断点击的位置是不是为头部
        if (
          clientX > EloffsetLeft &&
          clientX < EloffsetLeft + elW &&
          clientY > EloffsetTop &&
          clientY < EloffsetTop + 100
        ) {
          //如果是头部
          e.preventDefault(); // 移动时禁用默认事件
        } else {
          document.onmousemove = function (e) {
            //鼠标拖拽
            if (
              clientX > EloffsetLeft + elW - resizeW  &&
              clientX < EloffsetLeft + elW
            ) {
              //往左拖拽
              if (clientX > e.clientX) {
                if (dragDom.clientWidth < minWidth) {
                } else {
                  dragDom.style.width = elW - (clientX - e.clientX) * 2 + "px";
                }
              }
              //往右拖拽
              if (clientX <= e.clientX) {
                let targetTW = elW + (e.clientX - clientX) * 2
                targetTW > windowW ?
                  dragDom.style.width = windowW + "px" :
                  dragDom.style.width = targetTW + "px"
              }
            }
            //底部鼠标拖拽位置
            if (
              ELscrollTop + clientY > EloffsetTop + elH - resizeH &&
              ELscrollTop + clientY < EloffsetTop + elH
            ) {
              //往上拖拽
              if (clientY > e.clientY) {
                if (dragDom.clientHeight < minHeight) {
                } else {
                  dragDom.style.height = elH - (clientY - e.clientY) * 1 + "px";
                  dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
                }
              }
              //往下拖拽
              if (clientY <= e.clientY) {
                e.clientY >= windowH ?
                  dragDom.style.height = windowH - dragDom.offsetTop + "px" :
                  dragDom.style.height = elH + (e.clientY - clientY) * 1 + "px";
                dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
              }
            }
          };
          //结束
          document.onmouseup = function (e) {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        }
      };
    };
  }
});
export default Vue.directive('SkDialogDrag')

将skdialog.js注册为指令:

目录:

el–dialog如何放大缩小,element,ui,vue.js,前端

import SkDialogDrag from './dialog/skdialog'
const install = function(Vue) {
  Vue.directive('SkDialogDrag', SkDialogDrag)
}

指令使用:(v-指令名称(SkDialogDrag))

el–dialog如何放大缩小,element,ui,vue.js,前端

效果图:

el–dialog如何放大缩小,element,ui,vue.js,前端

注:吃水不忘挖井人,在 原作者wjqocean 的基础之上改进文章来源地址https://www.toymoban.com/news/detail-767979.html

到了这里,关于基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • element UI组件库el-dialog内程序刷新el-dialog内组件方法

    1、牢牢记住,vue是基于JavaScript ES6的,所以只要刷新页面里面data下的数据,页面会自动刷新的。 所以这个数据是父页面传给el-dialog的,要刷新父页面的数据,el-dialog页面内的组件就可以刷新了。 2、在页面的组件处理后台程序完成后,可以调用 that.$parent.$parent.【父页面的方

    2024年02月13日
    浏览(27)
  • element-ui:多个el-dialog弹框切换会出现闪烁

    使用多个element-ui组件el-dialog弹框切换 打开A弹框,点击关闭,紧接着打开B弹框 会出现一个明显的闪烁 给第一个弹框关闭加一点延迟 参考 【ElementUI】dialog弹窗出现闪屏问题解决办法

    2024年02月11日
    浏览(32)
  • element-ui中更换el-dialog弹窗中默认的关闭按钮

    在使用 element-ui 框架里的 el-dialog 组件时,要修改弹窗里默认的关闭图标;如下图所示:左边是想要替换后的;右边是组件默认的关闭图标; 通过检查组件的元素;发现组件默认的关闭是一个图标;通过图标的形式展现的。 那就可以通过 CSS 隐藏当前的图标;然后在当前图标

    2024年02月12日
    浏览(29)
  • element-ui框架的el-dialog弹出框被遮罩层挡住

    解决办法 在el-dialog标签里添加 :modal-append-to-body=‘false’ 问题分析  先来看看element-ui官网提供的属性说明文档 文档解释: 翻译成大白话就是,若el-dialog弹出框设置了modal-append-to-body=\\\'true\\\'(默认)属性,它的遮罩层就会被插入到body标签下(即与组件所在的最外层div同一层级),

    2024年02月16日
    浏览(28)
  • vue2.x 二次封装element ui 中的el-dialog

    在做后台管理系统的时候,dialog组件是我们使用频率比较高的组件,但是有一些需求现有的组件是不满足的。因此会需要我们做二次封装。 组件本身的属性我们保留,只需要根据需求添加,然后在使用的时候props去拿取使用就可以了。 本次遇到的问题是如何在父组件去控制

    2024年02月07日
    浏览(34)
  • element-ui el-dialog如何设置响应式宽高且永远水平垂直居中

            el-dialog是使平常使用element-ui比较常用的一个组件,想要灵活控制它达到想要的开发效果,就必须要熟悉它默认一些属性:默认 width:50% , 高度 为标题和el-dialog__body,el-dialog__footer 内容以及padding撑开 ,定位上 默认水平居中,距离顶端15vh         原理是width采

    2024年02月11日
    浏览(31)
  • Vue中使用element-ui el-dialog弹窗最大化还原,拖拽,动态改变大小

    创建对应的js文件   先在指定稳定文件创建js文件,如src下创建diaLog.js文件,部分会提示红色爆红,可以不予理会,可以根据需求修改,如:弹框可拉伸最小宽高。   2. 在main.js的引用   同时为了防止冲突,需要关闭closeOnClickModal(弹窗默认点击遮罩改为不关闭),并添加标签

    2024年02月11日
    浏览(31)
  • [element-ui] v-click-outside与el-dialog同时存在,出现的Bug

    背景 : v-click-outside 点击盒子aaa外部,盒子aaa隐藏 问题 :因为 el-dialog 绑在了body上,点击 el-dialog 里的任意内容,盒子aaa也隐藏了。 需求 :点击 el-dialog 里的任意内容,盒子aaa不隐藏 解决:给 el-dialog 加上 @click.native.stop 来阻止 el-dialog 内部的点击事件冒泡。

    2024年02月11日
    浏览(33)
  • element ui中父子组件共用一个el-dialog弹窗,切换组件页面弹窗进行关闭

    在Element UI中,如果多个父子组件共用一个el-dialog弹窗,并且需要在切换组件页面时关闭弹窗,你可以考虑以下方法来实现: 在Vuex中创建一个状态来管理弹窗的显示状态(例如,showDialog)。 在父子组件中都可以访问这个状态,以便共享。 当需要打开或关闭弹窗时,分发对应

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包