做一个可移动的弹窗(VUE)

2021-11-02  本文已影响0人  陈桑

前言:这里做一个可移动的弹窗,因为项目中使用到,且在写的时候发现很多坑。希望以后用到能够避免踩坑,特此记录。
示例:

可移动的弹窗示例

可移动的弹窗组件:

<template>
  <div class="dialogView">
    <div class="dialogBox" ref="dialogEl" :style="{marginLeft:ml,marginTop:mt}">
      <header class="dialogHeader" @mousedown="mouseDown">
        <el-button @click="closeDialog">关闭</el-button>
      </header>
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "moveDialog",
  props: {},
  data() {
    return {
      ml:'20%',
      mt:'10%',
      dialogB: false,
    };
  },
  mouonted() {},
  methods: {
    closeDialog(){
      this.ml='20%';
      this.mt='10%';
      return this.$emit('close')
    },
    mouseDown(e){
      let windowH = window.innerHeight;//获取浏览器的可用高度
      // let windowW = window.innerWidth;//获取浏览器的可用宽度
      let el = this.$refs.dialogEl;//获取需要拖拽移动的容器
      var disX = e.clientX - el.offsetLeft;
      var disY = e.clientY - el.offsetTop;
      this.dialogB = true;
      document.onselectstart = function () {return false} // 使用js禁止用户选中网页上的内容(解决拖动会选中文字的问题,来源:https://blog.csdn.net/china_skag/article/details/41648647)
      document.onmousemove = (e) => {
        if (!this.dialogB) return false
        let left = e.clientX - disX
        let top = e.clientY - disY
        if (top < 0 || top > windowH - 40) return false;//当到达顶部或者底部时就不让继续拖动了
        this.ml = left + 'px'
        this.mt = top + 'px'
      }
      document.onmouseup = () => {
        if (!this.dialogB) return false
        this.dialogB = false
      }
    },
  },
};
</script>

<style scoped lang="scss">
.dialogView{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0,0,0,.5);
  .dialogBox{
    width: 60%;
    height: 50%;
    background-color: #ffffff;
    .dialogHeader{
      height: 40px;
      cursor: all-scroll;
      display: flex;
      flex-direction: row-reverse;
      box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)
    }
  }
}
</style>

这里我没有使用弹性布局使弹窗组件进行居中,因为在设置后会和距离冲突。应该可以加一个动态的类,在鼠标摁下事件触发时把该类去除。
使用组件:
引入:

import moveDialog from '@/components/moveDialog.vue'// 引入组件

注册为局部组件:

components: {
    moveDialog,//注册为局部组件
},

创建一个变量记录显示隐藏

data(){
      return{
          dialogShow:false,//创建一个记录弹窗显示隐藏的变量
      }
  },

在template内使用组件:

<div v-show = 'dialogShow'>
      <!-- 接收组件发射出来的关闭事件 -->
      <moveDialog @close = "closeDialog" >
        <h3>这里面可以放任何的东西,所谓弹窗的内容。</h3>
      </moveDialog>
    </div>

关闭弹窗:

  methods:{
      // 关闭弹窗(子组件发射出来的自定义事件)
      closeDialog(){
          this.dialogShow = false;
      },
  },

代码都加了注释,很容易看懂。为了以后方便使用,特别记录。

上一篇下一篇

猜你喜欢

热点阅读