百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Vue实现拖拽穿梭框功能四种方式

toyiye 2024-06-21 12:06 12 浏览 0 评论

一、使用原生js实现拖拽

打开视频讲解更加详细

Vue实现拖拽穿梭框功能的四种方式_哔哩哔哩_bilibili

<html>

    <head>

      <meta charset="UTF-8" />

      <title>Lazyload</title>

      <style>

        .drag {

          background-color: skyblue;

          position: absolute;

          line-height: 100px;

          text-align: center;

          width: 100px;

          height: 100px;

        }

      </style>

    </head>

    <body>

      <!-- left和top要写在行内样式里面 -->

      <div style="left: 0; top: 0">按住拖动</div>

      <script src="./jquery-3.6.0.min.js"></script>

      <script>

        // 获取DOM元素

        let dragDiv = document.getElementsByClassName('drag')[0]

        // 鼠标按下事件 处理程序

        let putDown = function (event) {

          dragDiv.style.cursor = 'pointer'

          let offsetX = parseInt(dragDiv.style.left) // 获取当前的x轴距离

          let offsetY = parseInt(dragDiv.style.top) // 获取当前的y轴距离

          let innerX = event.clientX - offsetX // 获取鼠标在方块内的x轴距

          let innerY = event.clientY - offsetY // 获取鼠标在方块内的y轴距

          // 按住鼠标时为div添加一个border

          dragDiv.style.borderStyle = 'solid'

          dragDiv.style.borderColor = 'red'

          dragDiv.style.borderWidth = '3px'

          // 鼠标移动的时候不停的修改div的left和top值

          document.onmousemove = function (event) {

            dragDiv.style.left = event.clientX - innerX + 'px'

            dragDiv.style.top = event.clientY - innerY + 'px'

            // 边界判断

            if (parseInt(dragDiv.style.left) <= 0) {

              dragDiv.style.left = '0px'

            }

            if (parseInt(dragDiv.style.top) <= 0) {

              dragDiv.style.top = '0px'

            }

            if (

              parseInt(dragDiv.style.left) >=

              window.innerWidth - parseInt(dragDiv.style.width)

            ) {

              dragDiv.style.left =

                window.innerWidth - parseInt(dragDiv.style.width) + 'px'

            }

            if (

              parseInt(dragDiv.style.top) >=

              window.innerHeight - parseInt(dragDiv.style.height)

            ) {

              dragDiv.style.top =

                window.innerHeight - parseInt(dragDiv.style.height) + 'px'

            }

          }

          // 鼠标抬起时,清除绑定在文档上的mousemove和mouseup事件

          // 否则鼠标抬起后还可以继续拖拽方块

          document.onmouseup = function () {

            document.onmousemove = null

            document.onmouseup = null

            // 清除border

            dragDiv.style.borderStyle = ''

            dragDiv.style.borderColor = ''

            dragDiv.style.borderWidth = ''

          }

        }

        // 绑定鼠标按下事件

        dragDiv.addEventListener('mousedown', putDown, false)

      </script>

    </body>

  </html>

二、VUe使用js实现拖拽穿梭框

<template>

  <div>

    <h3 style="text-align: center">拖拽穿梭框</h3>

    <div id="home" @mousemove="mousemove($event)">

      <div>

        <span

         

          :id="'mouse' + index"

          v-for="(item, index) in leftData"

          :key="item.id"

          @mousedown="mousedown(index, 1)"

          @mouseup="mouseup(item, 1, index)"

        >

          <span>{{ item.label }}</span>

          <span @click="handerClickX(item, index, 1)"

            >X</span

          >

        </span>

      </div>

      <div>

        <span

         

          :id="'deleteMouse' + index"

          v-for="(item, index) in rightData"

          :key="item.id"

          @mousedown="mousedown(index, 2)"

          @mouseup="mouseup(item, 2, index)"

        >

          <span>{{ item.label }}</span>

          <span @click="handerClickX(item, index, 2)"

            >X</span

          >

        </span>

      </div>

    </div>

  </div>

</template>



<script>

export default {

  name: "home",

  data() {

    return {

      leftData: [

        { label: "首页", id: 1 },

        { label: "咨询", id: 2 },

        { label: "生活", id: 3 },

        { label: "财富", id: 4 },

        { label: "我的", id: 5 },

      ],

      rightData: [{ label: "世界", id: 6 }],

      isMoveTrue: false,

      isMove: false,

      moveId: "",

    };

  },

  mounted() {},

  components: {},

  methods: {

    mousedown(index, val) {

      this.isMoveTrue = true;

      if (val == 1) {

        this.moveId = "mouse" + index;

      } else {

        this.moveId = "deleteMouse" + index;

      }

    },

    mousemove(event) {

      if (this.isMoveTrue) {

        this.isMove = true;

        document.getElementById(this.moveId).style.position = "absolute";

        document.getElementById(this.moveId).style.top = event.clientY + "px";

        document.getElementById(this.moveId).style.left = event.clientX + "px";

        document.getElementById(this.moveId).style.transform =

          "translate(-50%,-50%)";

      }

    },

    mouseup(item, val, index) {

      if (!this.isMove) {

        this.isMoveTrue = false;

        this.moveId = "";

      }

      if (this.isMoveTrue && val == 2) {

        this.$nextTick(() => {

          this.rightData.splice(index, 1);

          this.leftData.push(item);

        });

      } else if (this.isMoveTrue && val) {

        this.leftData.splice(index, 1);

        this.rightData.push(item);

      }

      document.getElementById(this.moveId).style.display = "none";

      this.isMoveTrue = false;

      this.isMove = false;

      this.moveId = "";

    },

    handerClickX(item, index, val) {

      if (val == 1) {

        this.leftData.splice(index, 1);

        this.rightData.push(item);

      } else {

        this.rightData.splice(index, 1);

        this.leftData.push(item);

      }

    },

  },

};

</script>



<style scoped>

#home {

  display: flex;

  justify-content: space-around;

}

.tree-select-content {

  width: 40%;

  height: 300px;

  background: #f9faff;

  border: 1px solid #dee0ec;

  border-radius: 4px;

  display: flex;

  flex-wrap: wrap;

  align-content: baseline;

}

.select-content {

  width: max-content;

  height: 20px;

  padding: 1.6%;

  border: 1px solid #d6dbed;

  margin: 2% 1% 0;

  background: #ffffff;

  box-shadow: 0 0 8px 0 rgba(72, 119, 236, 0.1);

  border-radius: 4px;

}

.select-content:hover span {

  color: #4877ec;

}

.select-content:hover {

  cursor: pointer;

  background: #f8faff;

  border: 1px solid #3e75f4;

}

.select-text {

  font-size: 15px;

  color: #2e2f36;

  text-align: center;

  font-weight: 400;

}

.select-text-X {

  font-size: 15px;

  color: #4877ec;

  letter-spacing: 0;

  font-weight: 400;

  margin-left: 12px;

  cursor: pointer;

}

</style>

效果图:

三、Vue 拖拽组件 vuedraggable

`vuedraggable` 是标准的组件式封装,并且将可拖动元素放进了 `transition-group` 上面,过渡动画都比较好。

使用方式:

yarn add vuedraggable



import vuedraggable from 'vuedraggable';

在使用的时候,可以通过 v-model 来双向绑定本地 data,如果需要更新或者是触发父组件监听的事件,可以在 updated() 中去 emit。

案例:

<template>

  <div>

    <div>{{ drag ? "拖拽中" : "拖拽停止" }}</div>

    <!--使用draggable组件-->

    <draggable

      v-model="myArray"

      chosenClass="chosen"

      forceFallback="true"

      group="people"

      animation="1000"

      @start="onStart"

      @end="onEnd"

    >

      <transition-group>

        <div v-for="element in myArray" :key="element.id">

          {{ element.name }}

        </div>

      </transition-group>

    </draggable>

    <div>

      <div

       

        v-for="color in colors"

        v-dragging="{ item: color, list: colors, group: 'color' }"

        :key="color.text"

      >

        {{ color.text }}

      </div>

    </div>

  </div>

</template>

  <style scoped>

/*被拖拽对象的样式*/

.item {

  padding: 6px;

  background-color: #fdfdfd;

  border: solid 1px #eee;

  margin-bottom: 10px;

  cursor: move;

}

/*选中样式*/

.chosen {

  border: solid 1px #3089dc !important;

}

</style>

  <script>

//导入draggable组件

import draggable from "vuedraggable";

export default {

  //注册draggable组件

  components: {

    draggable,

  },

  data() {

    return {

      drag: false,

      //定义要被拖拽对象的数组

      myArray: [

        { people: "cn", id: 10, name: "www.itxst.com" },

        { people: "cn", id: 20, name: "www.baidu.com" },

        { people: "cn", id: 30, name: "www.taobao.com" },

        { people: "us", id: 40, name: "www.yahoo.com" },

      ],

      colors: [

        {

          text: "Aquamarine",

        },

        {

          text: "Hotpink",

        },

        {

          text: "Gold",

        },

        {

          text: "Crimson",

        },

        {

          text: "Blueviolet",

        },

        {

          text: "Lightblue",

        },

        {

          text: "Cornflowerblue",

        },

        {

          text: "Skyblue",

        },

        {

          text: "Burlywood",

        },

      ],

    };

  },

  methods: {

    //开始拖拽事件

    onStart() {

      this.drag = true;

    },

    //拖拽结束事件

    onEnd() {

      this.drag = false;

    },

  },

};

</script>

四、Awe-dnd指令封装

vue-dragging 的 npm 包的名字是 awe-dnd ,并不是 vue-dragging,这个库的特点是封装了 v-dragging 全局指令,然后通过全局指令去数据绑定等。

相比及 vuedraggable 来说, awe-dnd 是没有双向绑定(这里没有双向绑定并不是很严谨,准确的来说没有暴露双向绑定的方式),因此提供了事件,在拖拽结束的时候用来更新列表(不需要手动更新列表,其实内部是实现了双向绑定的)或者是去触发父组件监听的事件。

安装依赖:

npm install awe-dnd --save

yarn add awe-and

main.js

import VueDND from 'awe-dnd'



Vue.use(VueDND)

案例:

<template>

  <div>

    <div>

      <div

       

        v-for="color in colors"

        v-dragging="{ item: color, list: colors, group: 'color' }"

        :key="color.text"

      >

        {{ color.text }}

      </div>

    </div>

  </div>

</template>

<style scoped>

/*被拖拽对象的样式*/

.item {

  padding: 6px;

  background-color: #fdfdfd;

  border: solid 1px #eee;

  margin-bottom: 10px;

  cursor: move;

}

/*选中样式*/

.chosen {

  border: solid 1px #3089dc !important;

}

</style>

<script>

export default {

  data() {

    return {

      drag: false,

      colors: [

        {

          text: "Aquamarine",

        },

        {

          text: "Hotpink",

        },

        {

          text: "Gold",

        },

        {

          text: "Crimson",

        },

        {

          text: "Blueviolet",

        },

        {

          text: "Lightblue",

        },

        {

          text: "Cornflowerblue",

        },

        {

          text: "Skyblue",

        },

        {

          text: "Burlywood",

        },

      ],

    };

  },

  methods: {},

};

</script>

若对您有帮助,请点击跳转到B站一键三连哦!感谢支持!!!「链接」

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码