Vue多级弹窗
先来看下动态图效果
代码实现部分
爆竹声中一岁除
![a3357ed6883fd2250238a1cc37f0f9f1.png](https://i-blog.csdnimg.cn/blog_migrate/345f320dfb8205af15ea5daf8179fbec.png)
相比较那些很酷炫的在浏览器实现多窗口打开、拖动,以及缩放的语言,Vue也是可以实现这种效果的,这次来分享个基于Vue实现的多窗口弹出Demo。
![7871db64477b6e800cf95977ee14776c.png](https://i-blog.csdnimg.cn/blog_migrate/223513abafc5142eba1fcdf0ba09dc82.png)
![7871db64477b6e800cf95977ee14776c.png](https://i-blog.csdnimg.cn/blog_migrate/223513abafc5142eba1fcdf0ba09dc82.png)
这个Demo实现了多窗口弹出、拖动、支持点击窗口获取焦点
![7871db64477b6e800cf95977ee14776c.png](https://i-blog.csdnimg.cn/blog_migrate/223513abafc5142eba1fcdf0ba09dc82.png)
<template> <div class="hello"> <div class="just-click" @click="clickRect('101')" style="left:200px;top:300px;font-size: 32px;color: red;">墨div> <div class="just-click" @click="clickRect('102')" style="left:400px;top:300px;font-size: 32px;color: green;">点div> <div class="just-click" @click="clickRect('103')" style="left:600px;top:300px;font-size: 32px;color: blue;">白div> <div v-for="devOne in devDialogs" :key="devOne.devCode" class="multi-dialog" :id="devOne.box" :style="{'z-index':zindexValue,left: devOne.left, top: devOne.top}"> <div class="multi-dialog-title" :id="devOne.title"> <div>{{ devOne.devCode }} {{zindexValue}}div> <button type="button" class="el-dialog__headerbtn el-icon-close" @click="closeDialog(devOne)"> button> div> <div class="multi-dialog-content"> <pre> 春节是我国一个古老的节日,也是全年最重要的一个节日, 如何过庆贺这个节日,在千百年的历史发展中, 形成了一些较为固定的风俗习惯,有许多还相传至今。 pre> div> div> div>template><script>export default { name: 'HelloWorld', data () { return { devDialogs: [], /* 动态设置样式部分*/ zindexValue:"20", /* 当前编辑的弹窗的名称也就是id值*/ nowIdValue:"", indexInfo:30000 } }, methods:{ // 点击设备按钮弹出弹框 clickRect (val) { // 动态展示设备弹框 let exist = false this.devDialogs.forEach(element => { if (val === element.devCode) { exist = true } }) if (!exist) { let devOne = { devCode: val, box: 'box' + val, title: 'title' + val, left: '30%', top: '15%', indexValue:"20" } this.devDialogs.push(devOne) this.$nextTick(() => { this.divMove(devOne.title, devOne.box) }) } }, // 关闭设备弹框 closeDialog (devOne) { this.devDialogs.forEach(function (item, index, arr) { if (item.devCode === devOne.devCode) { arr.splice(index, 1) } }) }, // 移动设备弹框 divMove (titleId, boxId) { let that = this; let title = document.getElementById(titleId) // 获取点击元素(可选中拖动的部分) let box = document.getElementById(boxId) // 获取盒子元素(需要移动的整体) let divX = 0 // div的x坐标 let divY = 0 // div的y坐标 let isDrop = false // 是否可拖动 按下鼠标置为true 松开鼠标置为false let self = this // 将鼠标点击事件绑定在顶部title元素上 // var indexInfo = 30000; var abc = []; title.onmousedown = function (e) { /* 实现点击聚焦,将当前点击的窗口显示在最前面*/ that.indexInfo = that.indexInfo + 1; let boxValue = document.getElementById(boxId) /* 因为使用同一个可能会弹窗出现多次点击才能置顶,所以我们在这里写一个逻辑,保证每次点击之后,自己的zindex的*/ // console.log("%c"+that.indexInfo,"color:red") // console.log("%c"+abc,"color:bule") boxValue.style.zIndex=that.indexInfo; let el = e || window.event // 获取鼠标位置 divX = el.clientX - box.offsetLeft // 鼠标相对盒子内部的坐标x divY = el.clientY - box.offsetTop // 鼠标相对盒子顶部的坐标y isDrop = true // 设为true表示可以移动 document.onmousemove = function (e) { // 是否为可移动状态 if (isDrop) { let el = e || window.event let leftX = el.clientX - divX // 盒子距窗口左边的距离 let leftY = el.clientY - divY // 盒子距窗口顶部的距离 // 盒子不超出窗口的最大移动位置 即拖动置右下角时 // let maxX = document.documentElement.clientWidth - box.offsetWidth // 窗口宽度-盒子宽度 // let maxY = document.documentElement.clientHeight - box.offsetHeight // 窗口高度-盒子高度 let maxX = document.documentElement.clientWidth - 20 // 窗口宽度-盒子宽度 let maxY = document.documentElement.clientHeight - 20 // 窗口高度-盒子高度 // 当移动到最左最上时,leftX < 0、leftY < 0,盒子左边距、上边距取最大值0 // 当移动到最右最下时,leftX > maxX、leftY > maxY、已超出边界,盒子左边距、上边距取maxX、maxY leftX = Math.min(maxX, Math.max(0, leftX)) leftY = Math.min(maxY, Math.max(0, leftY)) box.style.left = leftX + 'px' box.style.top = leftY + 'px' } } document.onmouseup = function () { // 防止删除上一个div,下一个div挪位到上一个,需要在停止移动时给div赋位置 self.devDialogs.forEach(function (item) { if (item.box === boxId) { item.left = box.style.left item.top = box.style.top } }) isDrop = false document.onmousemove = null document.onmouseup = null } }} }}script><style >.just-click { cursor: pointer; width: 100px; height: 40px; position: fixed; background: white; color: black; line-height: 40px; text-align: center;}.multi-dialog { position: fixed; width: 580px; background: rgba(255,255,255,1); box-shadow: 0px 0px 10px rgba(200,200,200,1); top: 20px; left: 20px; /* z-index: 10; */ font-size: 14px;}.multi-dialog-title { padding: 15px; border: 0px solid rgba(204,204,204,1); border-bottom: 1px solid rgba(200,200,200); cursor: move; font-size: 18px;}.multi-dialog-content { padding: 10px;}style>
![5002b1eb1004388f469484bc74d9bb2f.png](https://i-blog.csdnimg.cn/blog_migrate/212c93837b62814bac7bb0b5d513318b.png)
![5002b1eb1004388f469484bc74d9bb2f.png](https://i-blog.csdnimg.cn/blog_migrate/212c93837b62814bac7bb0b5d513318b.png)
若是需要在项目中使用,可以考虑优化代码,以更加的符合自己的项目,利用更深度的UI交互,使项目更加的人性化、更加的友好