vue实战——元素的拖拽 + 控制元素无法拖拽出盒子 + 随元素拖拽自适应变化大小的盒子

简介: vue实战——元素的拖拽 + 控制元素无法拖拽出盒子 + 随元素拖拽自适应变化大小的盒子

<template>
  <div
    id="box"
    class="mainBox"
    @mousemove="move"
    @mouseup="moveEnd"
    :style="{
      width: boxWidth + 'px',
      height: boxHeight + 'px',
    }"
  >
    <div
      id="node"
      @mousedown="moveStart"
      :style="{
        left: nodeData.x + 'px',
        top: nodeData.y + 'px',
      }"
      class="node"
    ></div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      status: null,
      nodeData: {
        x: 10,
        y: 10,
      },
      // 移动的起点——鼠标按下时鼠标的坐标
      startX: null,
      startY: null,
      // 元素的初始位置
      nodeX: null,
      nodeY: null,
      // 盒子的初始大小
      boxWidth: 600,
      boxHeight: 300,
      // 盒子的坐标
      boxX: null,
      boxY: null,
    };
  },
  mounted() {
    let boxDOM = document.getElementById("box");
    this.boxX = boxDOM.clientLeft;
    this.boxY = boxDOM.clientTop;
  },
  methods: {
    // 开始移动
    moveStart(e) {
      if (e.target.id) {
        // 开启移动状态
        this.status = "move";
        // 获取鼠标初始坐标
        this.startX = e.clientX;
        this.startY = e.clientY;

        // 获取元素的初始位置
        let nodeDOM = document.getElementById("node");
        this.nodeX = nodeDOM.offsetLeft;
        this.nodeY = nodeDOM.offsetTop;
      }
    },
    // 移动中
    move(e) {
      if (this.status === "move") {
        // 元素的新位置 = 初始位置+(鼠标当前的坐标 - 鼠标初始坐标) 【即鼠标移动的距离】
        this.nodeData.x = this.nodeX + (e.clientX - this.startX);
        this.nodeData.y = this.nodeY + (e.clientY - this.startY);

        // 不能从左侧移出盒子
        if (this.nodeData.x < this.boxX) {
          this.nodeData.x = this.boxX;
        }
        // 不能从顶部移出盒子
        if (this.nodeData.y < this.boxY) {
          this.nodeData.y = this.boxY;
        }

        // 盒子大小随拖拽元素的位置自适应变化
        this.boxWidth = this.nodeData.x + 200;
        this.boxHeight = this.nodeData.y + 200;
      }
    },
    // 停止移动
    moveEnd() {
      // 关闭移动状态
      this.status = null;
    },
  },
};
</script>
<style scoped>
.mainBox {
  margin: 30px;
  position: relative;
  border: 1px solid black;
}
.node {
  position: absolute;
  cursor: move;
  background: red;
  height: 100px;
  width: 100px;
}
</style>

目录
相关文章
|
23小时前
|
JavaScript
Vue卸载eslint的写法,单独安装eslint,单独卸载eslint
Vue卸载eslint的写法,单独安装eslint,单独卸载eslint
|
23小时前
|
JavaScript
This dependency was not found:* vue/types/umd in ./src/router/index.jsTo install it, you can run
This dependency was not found:* vue/types/umd in ./src/router/index.jsTo install it, you can run
This dependency was not found:* vue/types/umd in ./src/router/index.jsTo install it, you can run
|
1天前
|
JavaScript 前端开发 程序员
Vue组件化、单文件组件以及使用vue-cli(脚手架)
Vue组件化、单文件组件以及使用vue-cli(脚手架)
11 0
|
1天前
|
JavaScript API
Vue数据动态代理机制的实现以及响应式与数据劫持
Vue数据动态代理机制的实现以及响应式与数据劫持
6 0
|
1天前
|
JavaScript 前端开发 程序员
Vue2入门(安装Vue、devtools,创建Vue)以及MVVM分层思想
Vue2入门(安装Vue、devtools,创建Vue)以及MVVM分层思想
7 0
|
Web App开发 JSON JavaScript
Vue 实战 (一) -- Vue 基础总结
Vue作为一个前端轻量级的MVVM框架有其独到之处,本文主要针对Vue1.0版本的官方文档进行梳理总结,主要包括以下几个方面:1.数据绑定2.指令3.组件4.事件5.过滤器
2403 0
|
1天前
|
JavaScript 区块链
vue 自定义网页图标 favicon.ico 和 网页标题
vue 自定义网页图标 favicon.ico 和 网页标题
9 1
|
2天前
|
存储 JavaScript 数据安全/隐私保护
vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)
vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)
12 1
|
2天前
|
JavaScript
vue实战——404页面模板001——男女手电筒动画
vue实战——404页面模板001——男女手电筒动画
8 1
|
1天前
|
JavaScript
vue中v-bind和v-model有什么区别?
在Vue.js中,v-bind和v-model都是指令,用于实现数据和DOM元素之间的双向绑定,但它们的使用场景和功能有所区别。
6 0