如何实现拖拽穿梭框功能?下面本篇文章给大家介绍一下Vue实现拖拽穿梭框功能四种方式,希望对大家有所帮助。
【相关推荐:vuejs视频教程】
一、使用原生js实现拖拽
<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 class="tree-select-content"> <span class="select-content" :id="'mouse' + index" v-for="(item, index) in leftData" :key="item.id" @mousedown="mousedown(index, 1)" @mouseup="mouseup(item, 1, index)" > <span class="select-text">{{ item.label }}</span> <span class="select-text-X" @click="handerClickX(item, index, 1)" >X</span > </span> </div> <div class="tree-select-content"> <span class="select-content" :id="'deleteMouse' + index" v-for="(item, index) in rightData" :key="item.id" @mousedown="mousedown(index, 2)" @mouseup="mouseup(item, 2, index)" > <span class="select-text">{{ item.label }}</span> <span class="select-text-X" @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 class="item" v-for="element in myArray" :key="element.id"> {{ element.name }} </div> </transition-group> </draggable> <div class="color-list"> <div class="color-item" 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 class="color-list"> <div class="color-item" 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>
以上是如何利用Vue实现拖拽穿梭框功能?四种方式介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

whenthevue.jsvirtualdomdetectschange,itupdatesthevirlualdom,diffsit和appliesminimalchangeStothereAldom.thisprocessensuresrocessensureshighhighpperformance byformance byavoidingunnnnnnnnnnneclastory dommaniplastions。

Vue.js的VirtualDOM既是真实DOM的镜像,又不完全是。1.创建和更新:Vue.js基于组件定义创建VirtualDOM树,状态变化时先更新VirtualDOM。2.差异和修补:通过diff操作比较新旧VirtualDOM,仅将最小变化应用到真实DOM。3.效率:VirtualDOM允许批量更新,减少直接DOM操作,优化渲染过程。VirtualDOM是Vue.js优化UI更新的战略工具。

Vue.js和React在可扩展性和可维护性上的表现各有优势。1)Vue.js易于上手,适合小型项目,CompositionAPI提升了大型项目可维护性。2)React适用于大型复杂项目,Hooks和虚拟DOM提高了性能和可维护性,但学习曲线较陡峭。

Vue.js和React的未来趋势和预测分别是:1)Vue.js将在企业级应用中广泛应用,并在服务端渲染和静态站点生成方面有突破;2)React将在服务器组件和数据获取方面创新,并进一步优化并发模式。

Netflix的前端技术栈主要基于React和Redux。1.React用于构建高性能的单页面应用,通过组件化开发提升代码重用性和维护性。2.Redux用于状态管理,确保状态变化可预测和可追踪。3.工具链包括Webpack、Babel、Jest和Enzyme,确保代码质量和性能。4.性能优化通过代码分割、懒加载和服务端渲染实现,提升用户体验。

Vue.js是一种渐进式框架,适用于构建交互性强的用户界面。其核心功能包括响应式系统、组件化开发和路由管理。1)响应式系统通过Object.defineProperty或Proxy实现数据监听,自动更新界面。2)组件化开发允许将界面拆分为可复用的模块。3)VueRouter支持单页面应用,提升用户体验。

Vue.js的主要缺点包括:1.生态系统相对较新,第三方库和工具不如其他框架丰富;2.学习曲线在复杂功能上变得陡峭;3.社区支持与资源不如React和Angular广泛;4.大型应用中可能遇到性能问题;5.版本升级与兼容性挑战较大。

Netflix使用React作为其前端框架。1.React的组件化开发和虚拟DOM机制提高了性能和开发效率。2.使用Webpack和Babel优化代码构建和部署。3.采用代码分割、服务端渲染和缓存策略进行性能优化。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

Atom编辑器mac版下载
最流行的的开源编辑器

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

禅工作室 13.0.1
功能强大的PHP集成开发环境

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Dreamweaver Mac版
视觉化网页开发工具