Vue项目开发中,可随意拖动弹窗。

描述:最近在做Vue项目开发中,使用了最近比较流行的ant-design-vue组件库,但是在在使用中,发现好多需要的组件都没有,然后就自己动手开发几个,该文章只是记录一个可拖动弹窗,其他在下一篇或者上一篇(输入框封装,表格的二次封装…)

基于Vue2和Ant-Design-Vue封装的后台系统,其中包括很多常用组件和方法Smile Admin

说明:该组件并不涉及任何UI库,原生封装,任何项目都可以使用。
原理其实,可以简化为,一个撑满屏幕的黑色背景,中间一个显示内容的白色区域,利用定位来做,但是底层的黑色背景层级一定要高,我们都知道,UI库的好多组件层级数都非常大,还有就是,获取元素的位置,和计算鼠标的移动的距离,最后赋值给定位元素就搞定了。

template部分

<template>
  <div class="modal_drag_wrap">
    <div class="wrap">
      <div class="modal_wrap" :style="{ width: width, height: height }">
        <div class="modal_title" ref="modalTitle" @mousedown="onMousedown">
          <span>
            <slot name="modalTitle"></slot>
          </span>
          <span>
            <a-icon type="close" @click="handlerClose"></a-icon>
          </span>
        </div>
        <div class="modal_main"></div>
        <div class="modal_foot">
          <a-button type="default" v-if="resetBtn" @click="handlerReset"
            >重置</a-button
          >
          <a-button type="default" @click="handlerClose">关闭</a-button>
          <a-button type="primary" v-if="submitBtn" @click="handlerSubmit"
            >提交</a-button
          >
        </div>
      </div>
    </div>
  </div>
</template>

script部分

<script>
/**
 * @author xue_yafei
 * @description :该组件,支持拖拽位置(默认上下左右居中),在调用的时候,只需传入参数(height、width,默认是width:67%,
 *               height:76%),下边分别有,重置(新增重置表单),关闭,提交(提交数据),三个按钮,和对应的
 *               function,默认只有关闭按钮。
 *
 * 调用案例:tryModal,在父级控制
 *          <modal-drag v-show="tryModal" :handlerClose="handlerClose">
 *               <template slot="modalTitle">弹窗标题</template>
 *          </modal-drag>
 *
 */
export default {
  name: "modalDrag",
  data() {
    return {};
  },
  props: {
    width: {
      type: String,
      default: "67%",
    },
    height: {
      type: String,
      default: "76%",
    },
    resetBtn: {
      type: Boolean,
      default: false,
    },
    submitBtn: {
      type: Boolean,
      default: false,
    },
    handlerClose: {
      type: Function,
      required: true,
    },
    handlerReset: Function,
    handlerSubmit: Function,
  },
  methods: {
    onMousedown(event) {
      let modalBox = document.getElementsByClassName("modal_wrap")[0];
      let e = event || window.event;
      let disX = e.clientX - modalBox .offsetLeft;
      let disY = e.clientY - modalBox .offsetTop;

      // 鼠标移动距离
      document.onmousemove = (e) => {
        let left = e.clientX - disX;
        let top = e.clientY - disY;

        // 限制移动距离
        let maxX = document.documentElement.clientWidth - modalBox .offsetWidth;
        let maxY = document.documentElement.clientHeight - modalBox .offsetHeight;
        left = Math.min(maxX, Math.max(0, left));
        top = Math.min(maxY, Math.max(0, top));
        //移动元素

        modalBox .style.left = left + "px";
        modalBox .style.top = top + "px";
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    },
  },
};
</script>

css部分

<style lang="less">
.wh {
  width: 100%;
  height: 100%;
}
.modal_drag_wrap {
  .wh;
  position: fixed;
  top: 0;
  left: 0;
  background: rgba(59, 59, 59, 0.5);
  z-index: 88;
  > .wrap {
    .wh;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    .modal_wrap {
      border-radius: 4px;
      background: white;
      position: absolute;
      .modal_title {
        height: 40px;
        width: 100%;
        padding: 0px 8px;
        border-bottom: 1px solid #ccc;
        cursor: pointer;
        display: flex;
        justify-content: space-between;
        line-height: 40px;
        font-weight: bolder;
        font-size: 16px;
        > span:last-child {
          &:hover {
            color: red;
          }
        }
      }
      .modal_main {
        background: lightcyan;
        height: calc(100% - 80px);
      }
      .modal_foot {
        height: 40px;
        border-top: 1px solid #ccc;
        display: flex;
        justify-content: flex-end;
        line-height: 40px;
        > .ant-btn {
          margin-right: 16px;
          margin-top: 3px;
        }
      }
    }
  }
}
</style>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐