Vue3封装可拖拽的弹窗

  • 核心代码(复制就可以使用了)
<template>
  <div :style="popupStyle">
    <div ref="dialogEl" class="popup" :style="{ left: ml, top: mt }">
      <div class="popup-tit" @mousedown="mouseDown">
        <div class="txt">{{ title }}</div>
        <div class="close" title="关闭" @click="close">X</div>
      </div>
      <div class="popup-content">
        <slot></slot>
      </div>
    </div>
  </div>
</template>
<script setup>
import { computed, ref } from 'vue';

const { width, height, title } = defineProps({
  width: {
    type: String,
    default: '623px',
  },
  height: {
    type: String,
    default: '379px',
  },
  title: {
    type: String,
    default: '',
  },
});
const emit = defineEmits(['close']);
const ml = ref('50%');
const mt = ref('50%');
const dialogEl = ref();
const dialogB = ref(false);

const size = computed(() => {
  let k = '',
    j = '';

  if (width.includes('rem')) {
    k = 'rem';
  } else if (width.includes('px')) {
    k = 'px';
  } else if (width.includes('vw')) {
    k = 'vw';
  }

  if (height.includes('rem')) {
    j = 'rem';
  } else if (height.includes('px')) {
    j = 'px';
  } else if (height.includes('vw')) {
    j = 'vw';
  }

  return {
    w: width.split(k)[0],
    h: height.split(j)[0],
    j,
    k,
  };
});

const popupStyle = computed(() => {
  const baseTitH = 65 / 390;

  return `--Tw:${width};--Th:${height};--titH:${baseTitH * size.value.h}${size.value.j};`;
});

const mouseDown = (e) => {
  let windowH = window.innerHeight; //获取浏览器的可用高度
  // let windowW = window.innerWidth;//获取浏览器的可用宽度
  let el = dialogEl.value; //获取需要拖拽移动的容器
  var disX = e.clientX - el.offsetLeft;
  var disY = e.clientY - el.offsetTop;

  dialogB.value = true;

  document.onselectstart = function () {
    return false;
  };

  document.onmousemove = (e) => {
    if (!dialogB.value) return false;

    let left = e.clientX - disX;
    let top = e.clientY - disY;

    if (top < 0 || top > windowH - 40) return false; //当到达顶部或者底部时就不让继续拖动了
    ml.value = left + 'px';
    mt.value = top + 'px';
  };

  document.onmouseup = () => {
    if (dialogB.value) {
      dialogB.value = false;
    }
  };
};

// 关闭
const close = () => {
  emit('close');
};
</script>
<style scoped lang="scss">
.popup {
  position: absolute;
  z-index: 100;
  display: flex;
  flex-direction: column;
  width: var(--Tw);
  height: var(--Th);
  padding: 5px 15px 15px 15px;
  background-image: url('../assets/images/icon/弹窗1.png');
  background-repeat: no-repeat;
  background-size: 100% 100%;
  transform: translateX(-50%) translateY(-50%);

  .popup-tit {
    position: relative;
    display: flex;
    box-sizing: border-box;
    width: 100%;
    height: var(--titH);
    padding-left: 40px;
    color: #fff;
    font-size: 20px;
    line-height: var(--titH);
    cursor: all-scroll;
    .close {
      position: absolute;
      right: 20px;
      cursor: pointer;
    }
  }
  .popup-content {
    flex: auto;
    // background-color: #fff;
  }
}
</style>

  • 使用方式
<script setup>
import TPopUp from '@/common/TPopUp.vue';
</script>

<template>
 <TPopUp  width="743px" height="469px" title="碳储量计算" @close="popVis=false">
      <div class="box">
        <div class="forms">
          <div class="form-item">
            <div class="lab">地上生物量:</div>
            <div class="numbers">1</div>
            <div class="numbers">2</div>
            <div class="numbers">3</div>
            <div class="numbers">4</div>
          </div>
          <div class="form-item">
            <div class="lab">地下生物量:</div>
            <div class="numbers">1</div>
            <div class="numbers">2</div>
            <div class="numbers">3</div>
            <div class="numbers">4</div>
          </div>
          <div class="form-item">
            <div class="lab">枯死木:</div>
            <div class="numbers">1</div>
            <div class="numbers">2</div>
            <div class="numbers">3</div>
            <div class="numbers">4</div>
          </div>
          <div class="form-item">
            <div class="lab">枯落物:</div>
            <div class="numbers">1</div>
            <div class="numbers">2</div>
            <div class="numbers">3</div>
            <div class="numbers">4</div>
          </div>
          <div class="form-item">
            <div class="lab">土壤有机质:</div>
            <div class="numbers">1</div>
            <div class="numbers">2</div>
            <div class="numbers">3</div>
            <div class="numbers">4</div>
          </div>
        </div>
    
 
      </div>
    </TPopUp>
</template>

你可能感兴趣的:(Vue3.0,javascript,前端,vue.js)