【前端开发】可拖拽浮窗组件

1. 组件:DragWindow

javascript 复制代码
<template>
  <div id="dragWindow" ref="dragBox" :style="{ width: width, height: height }">
    <div id="dragHead" @mousedown.stop="mouseDownHandler">
      <slot name="title"></slot>
    </div>
    <div id="dragBody">
      <slot name="content"></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "DragWindow",
  components: {},
  props: {
    title: {
      type: String,
      default: "",
    },
    width: {
      type: String,
      default: "300px",
    },
    height: {
      type: String,
      default: "100vh",
    },
  },
  data() {
    return {
      // 是否可以移动
      isMove: false,

      // 移动开始位置
      startPosition: {},
      // 元素当前位置
      currentPosition: {},

      // 拖拽元素
      dragHead: null,
    };
  },
  computed: {},
  created() {},
  mounted() {},
  methods: {
    mouseDownHandler(e) {
      // 获取元素当前位置
      this.currentPosition = {
        x: this.$refs.dragBox.offsetLeft,
        y: this.$refs.dragBox.offsetTop,
      };

      // 获取移动开始位置
      this.startPosition = {
        x: e.clientX,
        y: e.clientY,
      };

      // 设置为true,允许移动
      this.isMove = true;

      this.dragWindow = document.getElementById("dragWindow");

      // 鼠标移动事件
      this.dragWindow.addEventListener("mousemove", this.mouseMoveHandler);
      // 鼠标抬起事件
      this.dragWindow.addEventListener("mouseup", (e) => {
        this.isMove = false;
        this.dragWindow.removeEventListener(
            "mousemove",
            this.mouseMoveHandler
        );
      });
      // 鼠标移出事件
      this.dragWindow.addEventListener("mouseleave", (e) => {
        this.isMove = false;
        this.dragWindow.removeEventListener(
            "mousemove",
            this.mouseMoveHandler
        );
      });
    },

    // 鼠标移动事件
    mouseMoveHandler(e) {
      if (!this.isMove) {
        return;
      }

      // 获取鼠标移动的距离
      const nowX = e.clientX - this.startPosition.x,
          nowY = e.clientY - this.startPosition.y;

      // 计算并设置移动后的位置
      this.$refs.dragBox.style.left = `${this.currentPosition.x + nowX}px`;
      this.$refs.dragBox.style.top = `${this.currentPosition.y + nowY}px`;
    },

    // 关闭窗口
    close() {
      this.$emit("close");
    },
  },
};
</script>

<style lang="scss" scoped>
#dragWindow {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 999;
  transform: translate(-50%, -50%);
  background-color: #030e06;
  color: #fff;
  border-radius: 10px;

  #dragHead {
    width: 100%;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: rgba(#34a83a, 1);
    padding: 0px 10px 0px 20px;
    box-sizing: border-box;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    position: relative;

    .dragTitle {
      font-size: 18px;
    }

    .el-icon-close {
      font-size: 18px;
      cursor: pointer;

      &:hover {
        color: #ff6347;
      }
    }
  }

  #dragBody {
    width: 100%;
    height: calc(100% - 50px);
  }
}
</style>

2. main.js全局调用

javascript 复制代码
import DragWindow from './components/DragWindow/index.vue';
javascript 复制代码
    <DragWindow
        ref="DragWindow"
        w="600px"
        h="600px"
        title="可拖拽浮窗"
        @close="close()">
    </DragWindow>
相关推荐
前端Hardy1 分钟前
Vue3 的 v-model 双向绑定,90% 的人都用错了?(附 2026 最新避坑指南)
前端·javascript·vue.js
前端Hardy2 分钟前
救命!Vue3 的 Composition API,居然能让我少写 80% 冗余代码?(新手也能直接抄)
前端·javascript·vue.js
李剑一4 分钟前
前端必懂!一文搞懂 WebAssembly:Web/Electron/RN 全通用,你天天用的软件,底层都靠它
前端·webassembly
Definition16 分钟前
Claude Code 能养宠物了,体验下抽卡的感觉
前端·程序员
Daiyaosei20 分钟前
紧急安全警报:Axios npm 包被投毒事件详解与防护指南
前端·javascript·安全
We་ct25 分钟前
LeetCode 295. 数据流的中位数:双堆解法实战解析
开发语言·前端·数据结构·算法·leetcode·typescript·数据流
青槿吖28 分钟前
第一篇:Redis集群从入门到踩坑:3主3从保姆级搭建+核心原理一次性讲透|面试必看
前端·redis·后端·面试·职场和发展·bootstrap·html
美狐美颜sdk38 分钟前
2026主流直播美颜sdk对比:效果、算法与成本分析
前端·人工智能·计算机视觉·美颜sdk·直播美颜sdk·第三方美颜sdk·视频美颜sdk
王霸天40 分钟前
🚨 还在用 rem) 做大屏适配?用 vfit.js 一键搞定,告别改稿8版的噩梦!
前端·vue.js·数据可视化
文心快码BaiduComate1 小时前
Comate AI IDE三大能力升级:支持语音输入& AI可操作浏览器 & Figma设计与代码双向转换
前端·后端·程序员