基于vue制作的dragDialog拖拽弹窗组件
  hr26MWkbkYWR 2023年11月02日 102 0

📒 背景

最近项目中需要制作一个拖拽弹窗的交互(如下图展示),今天分享一下这个组件功能。希望能抛砖引玉,给大家带来启发。

基于vue制作的dragDialog拖拽弹窗组件_边距


🔍需求功能

1.点击打开,控制弹窗标题名称;

2.拖拽在浏览器范围内移动;

3.点击×可关闭;


👣设计开发

先说一下我的开发环境版本:

基于vue制作的dragDialog拖拽弹窗组件_拖拽_02

node: v11.3.0

npm: 6.4.1

vue:2.5.11

如果不是以上版本也没关系,今日分享的思路,相信你可以自己造出来~

首先是弹框,用html+css画出来,vue中控制显示隐藏v-show或v-if:

<div v-if="visible" class="my_dialog" id="dialogbig">
	<div class="my_dialog_box" id="my_dialog_box" v-drag >
  	<div class="my_dialog_title">
      {{showTitle}}
        <span class="my_dialog_close" @click="cancel"></span>
		</div>
		<!-- 内容 -->
		<div class="my_dialog_content"  id="content_box" >
      <slot></slot>
		</div>
  </div>
</div>

然后是其中v-drag绑定directives自定义指令:

directives: {
          drag: {
              inserted: function (el, binding, vnode) {
                  vnode = vnode.elm

                  let boxdom = document.getElementById('dialogbig');
                  let bigdom = document.getElementById('my_dialog_box');

                  el.onmousedown = ((event) => {
                      if (event.target.className !== "my_dialog_title") {
                          return
                      }
                      // (clientX, clientY)点击位置距离当前可视区域的坐标(x,y)
                      // offsetLeft, offsetTop 距离上层或父级的左边距和上边距

                      // 获取鼠标在弹窗中的位置
                      let mouseX = event.clientX - vnode.offsetLeft
                      let mouseY = event.clientY - vnode.offsetTop

                      let initClientX = event.clientX;

                      // 绑定移动和停止函数
                      document.onmousemove = ((event) => {
                          let left, top

                          // 获取新的鼠标位置(event.clientX, event.clientY)
                          // 弹窗应该在的位置(left, top)
                          left = event.clientX - mouseX
                          top = event.clientY - mouseY

                          let changeLeft;
                          changeLeft = event.clientX - initClientX;
                          let offsetLeft = boxdom.offsetLeft;


                          // offsetWidth、offsetHeight 当前元素的宽度
                          // innerWidth、innerHeight 浏览器可视区的宽度和高度

                          // 获取弹窗在页面中距X轴的最小、最大 位置
                          let minX = -vnode.offsetWidth / 2 + bigdom.offsetWidth
                          let maxX = window.innerWidth + vnode.offsetWidth / 2 - bigdom.offsetWidth
                          if (left <= minX) {
                              left = minX
                          } else if (left >= maxX) {
                              left = maxX
                          }

                          // 获取弹窗在页面中距Y轴的最小、最大 位置
                          let minY = vnode.offsetHeight / 2
                          let maxY =window.innerHeight + vnode.offsetHeight / 2 - bigdom.offsetHeight
                          if (top <= minY) {
                              top = minY
                          } else if (top >= maxY) {
                              top = maxY
                          }
                          // 赋值移动
                          vnode.style.left = left + 'px'
                          vnode.style.top = top + 'px'
                          //boxdom.style.left = offsetLeft + changeLeft +'px'
                         /* boxdom.style.top = top + 'px'*/
                      })
                      document.onmouseup = (() => {
                          document.onmousemove = document.onmouseup = null
                      })
                  })
                  window.onresize = (() => {
                      vnode.style.left = "50%"
                      vnode.style.top = "50%"
                  })
              }
          },
}          

其他页面调用:

 <button @click="isShow = true">打开</button>
  <dragDialog :visible="isShow" :showTitle="title" @confirm="onConfirm" @cancel="onCancel">
     <div class="text">我是弹框里的内容,可以随便放哦</div>
  </dragDialog>

基于vue制作的dragDialog拖拽弹窗组件_拖拽_03

更多逻辑代码欢迎体验组件--mycomponentsvue

npm install mycomponentsvue@0.0.18

import mycomponents from 'mycomponentsvue'

Vue.use(mycomponents)

<dragDialog :visible="isShow" :showTitle="title" @confirm="onConfirm" @cancel="onCancel">
     <div class="text">我是弹框里的内容,可以随便放哦</div>
  </dragDialog>

本组件只用于学习交流哈!所以名字起的比较随意!~


🚀写在最后

如果本文中有bug、逻辑错误,或者您有更好的优化方案欢迎评论联系我哦!~关注我持续分享日常工作中的组件设计和学习分享,一起进步加油!



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
hr26MWkbkYWR