Vue自定义组件——封装一个简单的可拖拽的弹出框 可拖拽的Dialog

2023-11-08

首先明确需要传入组件的属性:

* @Props: 
    dialogVisible  Number      非0打开
    allowDrag      Boolean     是否可以拖拽
    noFoot         Boolean     是否显示按钮行
    @submit        Function    点击提交按钮的回调
 -->

设计组件的组成部分,这里简单的加了一个遮罩,只有遮罩层和弹窗主体。

用到了h5的drag属性 HTML5 拖放 | 菜鸟教程

组件内部提供了title和connect两个插槽供使用。

插槽?插槽 — Vue.js

弹窗使用绝对定位供捕获鼠标位置后计算拖拽终点。

<template>
  <div class="dialog">
    <!-- 遮罩层 -->
    <div class="logOn" @click="showModal = 0" v-show="showModal" />
    <!-- 弹窗本体 -->
    <div
      class="modalOn"
      v-show="showModal"
      :draggable="allowDrag"
      @dragstart="dragstart"
      @dragend="dragend"
      ref="modal"
      :style="{ top: top + 'px', left: left + 'px' }"
    >
      <div class="head">
        <div>
          <slot name="title" />
        </div>
        <div @click="showModal = 0" class="x">×</div>
      </div>
      <div class="main">
        <slot name="connect" />
      </div>
      <!-- 底部按钮行 -->
      <div class="but_line" v-show="!noFoot">
        <el-button class="but" @click="showModal = 0">取消</el-button>
        <el-button class="but" type="primary" @click="submit"> 提交 </el-button>
      </div>
    </div>
  </div>
</template>

功能实现:dragstart可以获取到拖拽时鼠标相对于弹窗的位置坐标,dragend获得的拖拽后鼠标位置减去鼠标相对于弹窗的位置就是弹窗拖拽的实际位置。

这里用e.preventDefault()阻止了拖拽弹窗时的禁止放置图标

用e.dataTransfer.dropEffect = "move" 重新定义了拖拽时的可移动图标

什么是dataTransfer.dropEffect?  

DataTransfer.dropEffect - Web API 接口参考 | MDN

<script type="text/ecmascript-6">
export default {
  name: "dragModal",
  components: {},
  data() {
    return {
      showModal: 0, //是否打开弹窗 非0打开
      left: "",
      top: "",
    };
  },
  props: {
    //父组件传入的弹窗开关状态 非0打开
    dialogVisible: {
      type: Number,
      default: 0,
    },
    //是否能拖拽
    allowDrag: {
      type: Boolean,
      default: false,
    },
    //是否显示按钮行
    noFoot: {
      type: Boolean,
      default: false,
    },
  },
  mounted() {},
  computed: {},
  watch: {
    //监听父组件弹窗开关状态同步至组件
    dialogVisible() {
      this.showModal = this.dialogVisible;
    },
  },
  methods: {
    /**
     * @description: 拖拽前的回调
     * @param {Object} DragEvent
     * @return void
     */
    dragstart(e) {
      document.ondragover = function (e) {
        e.preventDefault();
        e.dataTransfer.dropEffect = "move";
      };
      //获取鼠标相对于拖拽元素的位置
      this.diffX = e.layerX;
      this.diffY = e.layerY;
    },
    /**
     * @description: 拖拽后的回调
     * @param {Object} DragEvent
     * @return void
     */
    dragend(e) {
      document.ondragover = function (e) {
        e.dataTransfer.dropEffect = "none";
      };
      //获取元素落点位置 鼠标位置-相对于拖拽元素的位置
      this.top = e.pageY - this.diffY;
      this.left = e.pageX - this.diffX;
    },
    submit() {
      this.$emit("submit");
    },
  },
};
</script>

一些简单的居中样式和类似el的遮罩样式

.dialog {
  display: flex;
  align-items: center;
  justify-content: center;
}

.logOn {
  background: rgba(0, 0, 0, 0.3);
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.modalOn {
  min-width: 600px;
  background: #fff;
  position: absolute;
  border-radius: 3px;
  padding: 12px;
}

.head {
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid #e6e6e6;
  height: 30px;
}
.x {
  width: 30px;
  display: flex;
  justify-content: center;
  cursor: pointer;
}
.main {
  padding: 12px;
}

.but {
  border-radius: 5px;
  height: 30px;
  line-height: 6px;
}

.but_line {
  display: flex;
  justify-content: flex-end;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue自定义组件——封装一个简单的可拖拽的弹出框 可拖拽的Dialog 的相关文章

随机推荐

  • 保持 SSH 连接

    SSH 总是被强行中断 尤其是用 VSCode 代码写的好好的 突然刷新窗口 不仅效率低 更惹人恼火 可以通过配置服务端或客户端的 SSH 来保持 SSH 链接 方法一 配置服务端 可以在服务端配置 让 server 每隔 30 秒向 cl
  • 力扣:最大值(Java)

    给定一组非负整数 nums 重新排列每个数的顺序 每个数不可拆分 使之组成一个最大的整数 注意 输出结果可能非常大 所以你需要返回一个字符串而不是整数 class Solution public String largestNumber i
  • redux总结兼开发者工具

    Redux简介 使用Hook实现功能 不使用redux Redux三大核心概念 完整版代码 未优化 Redux异步action react redux库 react redux数据共享 总结 合并reducers 单独写成一个文件 继续简写
  • web3钱包系统开发

    web3技术概念介绍 近期 演员周星驰在ins开通首个社交账号 并发布人才招募令 在漆黑中找寻鲜明出众的Web3人才 将 Web3 带入大众视野 但有不少人对其感到陌生 到底何为Web3 早在2018年 就有人开始谈论web3了 它其实是一
  • CSS中关于z-index的堆叠顺序

    1 同级的z index div class container div class div1 h1 Division Element 1 z index 10 h1 div div class div2 h1 Division Eleme
  • Vs2019简单快速的打包可安装项目(图文教程)

    声明本项目在已安装vs2019和加载了installer Projects的情况下才能操作 右键解决方案 gt 添加 gt 新建项目 新建一个Setup Project 进入这个页面 右键Application Foluder gt Add
  • CVPR 2023

    作者 张倩 小舟 来源 机器之心 在文生图领域 扩散模型似乎已经一统天下 让曾经也风头无两的 GAN 显得有些过时 但两相比较 GAN 依然存在不可磨灭的优势 这使得一些研究者在这一方向上持续努力 并取得了非常实用的成果 相关论文已被 CV
  • 遍历Github仓库并提取所有图片

    遍历Github仓库并提取所有图片 项目介绍 一个简易的Github图床客户端 项目仓库 GithubImageHost 利用 QElapsedTimer QCoreApplication processEvents 可是实现UI同步 QE
  • html静态页面中引入scss的样式调整

    问题 静态页面样式和vue动态页面的样式不统一 截图了一个角落 需求 静态页面的样式要和动态页面的一样 解决步骤 F12 查看样式文件引用的区别 找到vue动态页面中的样式区别是在vue项目中用了自带的scss文件 将文件引入到静态页面的文
  • SSH通道的Kettle链接MySQL方法

    参考文献 http www ukettle org thread 452 1 1 html 对于采用SSH通道的MySQL服务器 Kettle无法直接连接 需要使用到 使用 SSH 工具 PUTTY
  • yolov5的TensorRT部署--warpaffine_cuda核函数

    从0到1实现基于tensorrt的yolo部署教程 http t csdn cn HUn4T 请点击该链接 即可看到全文 本文对于上面的案例 将预处理使用cuda核函数进行加速 一 cuda核函数的基本概念 1 1 CUDA C基础 核函数
  • Redis入门(一)

    1 简介 Redis 是完全开源的 遵守 BSD 协议 是一个高性能的 key value 数据库 Redis 与其他 key value 缓存产品有以下三个特点 Redis支持数据的持久化 可以将内存中的数据保存在磁盘中 重启的时候可以再
  • 计算机组成原理实验二 存储系统预习报告

    实验一 静态RAM 一 实验目的 掌握静态随机存储器 RAM 工作特性及数据的读写方法 基于信号时序图 了解读写静态随机存储器的原理 二 实验预习 1 阅读实验指导书 然后回答问题 实验所用的静态存储器由一片 6116 2K 8bit 构成
  • 离散信号的Matlab表示

    对任意离散序列x k 需用2个向量来表示 一个表示k的取值范围 另一个表示序列的值 例如序列x k 2 1 1 1 3 0 2 可用Matlab表示为 k 2 4 x 2 1 1 1 3 0 2 若序列从0开始 则只用一个向量x就可表示序列
  • 前端开发: 微信小程序 (文字,链接)生成二维码

    首先最主要的还是通过weapp qrcode js 靠这个轮子就可以了 GitHub yingye weapp qrcode weapp qrcode js 在 微信小程序 中 快速生成二维码https github com yingye
  • 人工智能和机器学习

    机器学习 1 什么是机器学习 在进行特定的编程的情况下 给与计算机学习能力的领域 机器学习是从数据中自动分析获得模型 并利用模型对未知数据进行预测 2 机器学习与人工智能 2 1人工智能发展的三个阶段 1980年代是正式形成时期 1990
  • Java接口详解

    http hi baidu com cxgfhfiupuanour item 370967f74ecbe9cca835a2b4 对初学者来说 接口不是很好理解 现将某高手的一篇文章贴出来 共大家分享 我们来看一个类 class A priv
  • 华为UOS欧拉版 K3S+Rancher 安装完全版

    文章目录 K3S服务 happy path安装过程 1 准备工作 1 1 修改网卡名称为eth0 1 2 切换yum源 1 3 关闭防火墙以及selinux 1 4 修改主机名 并修改hosts 1 5 在UOS 基于华为欧拉 上安装doc
  • vue动画之轮播图

  • Vue自定义组件——封装一个简单的可拖拽的弹出框 可拖拽的Dialog

    首先明确需要传入组件的属性 Props dialogVisible Number 非0打开 allowDrag Boolean 是否可以拖拽 noFoot Boolean 是否显示按钮行 submit Function 点击提交按钮的回调