Vue:可拖拽组件

这篇具有很好参考价值的文章主要介绍了Vue:可拖拽组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        在实际开发中,很可能会遇到开发可拖拽组件的需求,目的是应对某些弹框组件会遮盖某些重要信息/可操作面板,通过可拖拽的形式可以将上层的弹框组件移动到其他位置,从而不影响整个系统的操作。下面,我们分两步走,开发一个可拖拽的弹框组件,最终效果如下图所示,

vue拖拽组件,Vue,vue.js,前端,javascript,可拖拽组件,单文件组件

 

Step-1:原生JS开发可拖拽弹框

        第一步,基于原生JS开发一个简陋版本的可拖拽弹框,基本效果贴在本部分最后,先看一下完整的示例代码吧,

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>可拖拽弹框</title>
  <style>
    *,
    html,
    body {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    body {
      background-color: #000;
    }

    .box {
      position: absolute;
      top: 15px;
      left: 200px;
      width: 400px;
      height: 300px;
      background-color: rgba(255, 255, 255, 0.3);
      border: 1px solid #fff;
    }
  </style>
</head>

<body>
  <div class="box" id="box"></div>
</body>
<script>
  let boxPos = {
    x: null,
    y: null
  }
  let startPos = {
    x: null,
    y: null
  }
  let isMove = false;
  const box = document.getElementById("box");

  box.addEventListener("mousedown", (e) => {
    const { clientX, clientY } = e;
    //获取元素的当前位置
    boxPos = {
      x: box.offsetLeft,
      y: box.offsetTop,
    };
    startPos = {
      x: clientX,
      y: clientY
    }
    isMove = true;
    document.body.style.cursor = "move";

    document.addEventListener("mousemove", (e) => {
      if (!isMove) return;
      const { clientX, clientY } = e;
      const [offsetX, offsetY] = [clientX - startPos.x, clientY - startPos.y];
      box.style.left = `${boxPos.x + offsetX}px`
      box.style.top = `${boxPos.y + offsetY}px`
    })
    document.addEventListener("mouseup", () => {
      isMove = false;
      document.body.style.cursor = "default";
    })
  })

</script>

</html>

        基本效果如下,PS:直接使用了黑色背景,弹框也没有做美化,因为我们的重点工作在后面的组件式开发。

vue拖拽组件,Vue,vue.js,前端,javascript,可拖拽组件,单文件组件

 

Step-2:Vue可拖拽弹框组件

        完整的示例代码如下,直接引入InfoBox.vue组件即可使用,

<template>
  <div v-if="show" ref="infoBox" class="info-box" :style="styleObject">
    <div class="nav" @mousedown.stop="mouseDownHandler">
      <span class="title">{{ title }}</span>
      <span class="iconfont close" @click="show = false">&#xe678;</span>
    </div>
    <div class="body">
      <slot name="content"></slot>
    </div>
  </div>
</template>
<script>
export default {
  name: "InfoBox",
  props: {
    width: {
      type: String,
      required: false,
      default: "400px",
    },
    height: {
      type: String,
      required: false,
      default: "300px",
    },
    title: {
      type: String,
      required: false,
      default: '点位详情'
    }
  },
  data() {
    return {
      styleObject: {
        width: "400px",
        height: "300px"
      },
      show: true,
      isMove:false,
    }
  },
  mounted() {
    this.styleObject = {
      height: this.$props.height,
      width: this.$props.width,
    }
  },
  methods: {
    mouseDownHandler(e) {
      const currentPosition = {x:this.$refs.infoBox.offsetLeft,y:this.$refs.infoBox.offsetTop};
      const startPosition = {x:e.clientX,y:e.clientY};//获取当前点击位置
      console.log(currentPosition,startPosition);
      this.isMove = true;
      //注册鼠标移动事件
      document.addEventListener("mousemove",(event_move)=>{
        if(!this.isMove) return;
          const offsetX = event_move.clientX - startPosition.x,
                offsetY = event_move.clientY - startPosition.y;
          console.log(offsetX,offsetY)
          //修改弹框位置
          this.$refs.infoBox.style.left = `${currentPosition.x + offsetX}px`;
          this.$refs.infoBox.style.top = `${currentPosition.y + offsetY}px`;
      })
      //注册鼠标抬起事件
      document.addEventListener("mouseup",()=>{
        this.isMove = false;
      })

    },
    mousemoveHandler() {

    },
    mouseUpHandler() {

    }
  }
}
</script>
<style lang="less" scoped>
.info-box {
  // .box-size(400px,300px);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: @base-box-bgColor;
  border: 1px solid #3374ac;
  z-index: 999999;

  .nav {
    padding: 5px 10px;
    height: 35px;
    background: @base-bg-color;
    .flex-layout('row');
    justify-content: space-between;

    .title {
      user-select: none; //禁止选中标题文字
      padding: 0px 5px;
      font-family: "AliMaMa";
      font-style: italic;
      font-size: 18px;
      color: #cee9f5;
      background-image: linear-gradient(to top, #00C6FF, #8AFFD2);
      /* 线性渐变背景,方向向上 */
      -webkit-background-clip: text;
      /* 背景被裁剪成文字的前景色 */
      -webkit-text-fill-color: transparent;
      /* 文字填充颜色变透明 */
    }

    .close {
      font-size: 20px;
      cursor: pointer;

      &:hover {
        color: rgb(0, 201, 252);
      }
    }
  }
}
</style>

        使用示例如下,文章来源地址https://www.toymoban.com/news/detail-654722.html

<!--
 * @Description: 
 * @Author: Xwd
 * @Date: 2023-02-15 22:26:06
 * @LastEditors: Xwd
 * @LastEditTime: 2023-02-18 21:08:26
-->
<template>
  <div id="app">
    <InfoBox/>
    <router-view/>
  </div>
</template>
<script>
//导入可拖拽弹框组件
import InfoBox from '@/layout/common/InfoBox.vue'
export default {
    name:"App",
    components:{
      InfoBox
    }
}
</script>
<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  .box-size(100vw,100vh);
}
</style>

到了这里,关于Vue:可拖拽组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3封装可拖拽的弹窗

    核心代码(复制就可以使用了) 使用方式

    2024年01月19日
    浏览(40)
  • 基于vue的可拖拽设计的报表看板设计器

    gitee上的不错项目,基于vue实现的可拖拽的看板设计器可以自由搭配颜色和图标,开发者可以只关注业务数据接口,前端不擅长的人员可以直接轻松上手。 1.可支持的元素 文字,边框,常见图表,柱形图,折线饼图等等,还有一些列表数据,当然还支持iframe嵌套,当组件满足

    2024年02月11日
    浏览(58)
  • Vue中使用vue-drag-resize实现窗体可拖拽和随意缩放大小

    若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_ruoyi本地调式_霸道流氓气质的博客-CSDN博客 在上面的基础上,实现弹窗窗体可移动以及随意缩放大小。 效果如下   注: 博客: https://blog.csdn.net/badao_liumang_qizhi 

    2024年02月11日
    浏览(38)
  • vue+echart实现3d地图可拖拽、缩放、区域填充颜色(geo3D)

    功能背景 一个略微比2d地图炫酷一些的3d地图, 1、可对区域进行不同颜色填充。 2、可拖拽缩放地图 3、鼠标悬停高亮某区域。 (注意:当开启了鼠标悬停series,并高亮某个数据的时候,会导致地图的拖拽缩放出现卡顿,因为相当于是事件重叠了。。。目前还没想到好的解决方

    2024年02月13日
    浏览(45)
  • vue2实现可拖拽甘特图(结合element-ui的gantt图)

      接到公司需求,要做一个可拖拽的甘特图来实现排期需求,官方的插件要付费还没有中文的官方文档可以看,就去找了各种开源的demo来看,功能上都不是很齐全,于是总结了很多demo,合在一起组成了一版较为完整的满足需求的甘特图。 1.拖拽  拖拽功能是甘特图的主要功

    2024年02月03日
    浏览(48)
  • 【庖丁解牛】vue-element-admin前端CRUD通用操作组件详解,对,核心就是crud.js文件

    vue-element-admin 框架之所以能够快速定制应用,得益于其通配的CRUD操作,属性配置多样化且个性化,能够满足绝大部分开发需求,也方便了代码生成。 可以深入学习重点源文件是: src/components/Crud/crud.js ,一共 863 行代码,以及下图中其它四个vue组件,形成了对通用CRUD操作的高

    2024年01月18日
    浏览(56)
  • vue3.0 安卓和ios h5 移动端音频自定义圆环可拖拽播放(兼容微信浏览器)

    安装  npm install weixin-js-sdk 引入 template     div class=\\\"circle_box\\\"         div id=\\\"content\\\"/div          img class=\\\"img_0\\\" src=\\\"https://img.yzcdn.cn/vant/cat.jpeg\\\" alt=\\\"\\\"          img @click=\\\"changeType\\\" class=\\\"img_1\\\" v-show=\\\"playbool\\\" src=\\\"@/assets/decompression/pressure_audio_play.png\\\" alt=\\\"\\\"          img @click=\\\"changeType\\\"

    2023年04月23日
    浏览(98)
  • 前端弹窗可拖拽功能实现

           前端弹窗可拖拽功能主要实现思路就是监听鼠标移动事件,根据鼠标位置实时修改弹窗距离父级窗口(或者屏幕,根据需求设置)的left和right,但是考虑到鼠标拖拽一般都是在div的标题栏处发生,鼠标按下的位置不可能是弹窗的左上角位置,为此需要计算 鼠标按下的

    2024年02月19日
    浏览(44)
  • Three.js实现模型,模型材质可拖拽效果 DragControls

    DragControls:是一个用于在Three.js中实现拖拽控制的辅助类。它简化了在Three.js中实现拖拽物体的过程。 DragControls的构造函数接受三个参数: objects:一个包含需要进行拖拽的物体的数组。 camera:相机对象,用于将屏幕坐标转换为三维空间坐标。 domElement:渲染器的DOM元素,用于

    2024年02月11日
    浏览(36)
  • Vue 组件中如何引入外部的js文件

    在Vue中,通常我们引入一个js插件都是使用 npm  方式下载然后 import 使用的。但是我现在本地有了js文件或者是一个远程js文件链接,我不想使用 npm install xxx  的方式,有什么办法吗? 简单粗暴,直接在Vue项目的 index.html  中使用全局的方式引入,比如: 缺点: 不使用该js插

    2024年02月08日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包