这篇文章将为大家详细讲解有关怎么利用vue组件实现图片的拖拽和缩放功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
前言
vue实现一个组件其实很简单但是要写出一个好的可复用的组件那就需要多学习和钻研一下,一个好的组件必须有其必不可少的有优点:一是能提高应用开发效率、测试性、复用性等;二是组件应该是高内聚、低耦合的;三是组件应遵循单向数据流的原则。
在实现我的图片的拖拽组件我们的搞清其原理,在这里我使用的是mousedown,mousemove和mouseup来实现拖拽。
如图所示:
方法如下:
新建ElementDrag.vue文件内容如下:
<template> <div class="drag-outer" ref="dragWrap" @mousemove="dragMousemove"> <div class="drag-inner" ref="dragElement" @mousedown="dragMousedown" @mouseup.stop="isMousedown = false"> <slot></slot> </div> </div></template>
定义moveStart用于记录拖拽元素初始位置。定义isMousedown变量来判断鼠标是否按下, 如果isMousedown === true鼠标移动就改变darg-inner位置。
<script>export default { name: 'ElementDrag', data() { return { isMousedown: false, //鼠标是否按下 moveStart: {x: 0, y: 0}, //拖拽元素初始位置 translate: {x: 0, y: 0}, //计算拖拽元素在下下x,y方向各移动了多少 scale: 1, //拖拽元素缩放值 } }, methods: { dragMousedown() { this.moveStart.x = event.clientX this.moveStart.y = event.clientY this.isMousedown = true }, dragMousemove() { if(this.isMousedown) { this.translate.x += (event.clientX - this.moveStart.x) / this.scale this.translate.y += (event.clientY - this.moveStart.y) / this.scale this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` this.moveStart.x = event.clientX this.moveStart.y = event.clientY } } }}</script>
样式部分我们设置外层drag-outer用flex布局让里面元素快速居中, user-drag: none;禁用图片等元素的可拖拽属性。
<style lang="scss" scoped>.drag-outer { width: 100%; height: 100%; overflow: hidden; display: flex; justify-content: center; align-items: center; .drag-inner { transform-origin: center center; display: flex; justify-content: center; align-items: center; cursor: move; user-select: none; >* { -webkit-user-drag: none; user-drag: none; } }}</style>
添加鼠标滚轮事件缩放drag-inner元素, e.wheelDelta为正表示放大,为负缩小,值越大表示滚动越快。通过scale控制拖拽元素缩放。同过对组件传值scaleZoom来控制其缩放最大最小程度值。
...methods: { props: { type: Object, default(){ return { min: 0.5, max: 5 } } }, ... handleScroll(e) { let speed = e.wheelDelta/120 if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) { this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){ this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` } }},mounted() { window.addEventListener('mousewheel',this.handleScroll,false) }
以上代码已经实现了功能我们预期的功能,但是为了更好的体验,需要进一步优化组件。添加isHover来控制鼠标是否移动到了drag-outer以外,如果isHover为false这时鼠标滚轮滚动不会缩放元素,并且将isMousedown设置为false。再使用插槽slot预览位置。
<template> <div class="drag-outer" ref="dragWrap" @mouseenter="isHover = true" @mouseleave="isHover = isMousedown = false" @mousemove="dragMousemove"> <div class="drag-inner" ref="dragElement" @mousedown="dragMousedown" @mouseup.stop="isMousedown = false"> <slot></slot> </div> </div></template>....data() { return { ..., isHover: false, }},methods: { ... handleScroll(e) { if(this.isHover) { let speed = e.wheelDelta/120 if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) { this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){ this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` } } }}
贴上组件的最终代码:
<template> <div class="drag-outer" ref="dragWrap" : @mouseenter="isHover = true" @mouseleave="isHover = isMousedown = false" @mousemove="dragMousemove"> <div class="drag-inner" ref="dragElement" : @mousedown="dragMousedown" @mouseup.stop="isMousedown = false"> <slot></slot> </div> </div></template><script>export default { name: 'ElementDrag', props: { outerOptions: { type: Object, default () { return { background: 'rgba(0,0,0,0.9)' } } }, innerOptions: { type: Object, default () { return { background: 'rgba(0,0,0,0.1)', } } }, scaleZoom: { type: Object, default () { return { max: 5, min: 0.2 } } } }, data() { return { isMousedown: false, isHover: false, moveStart: {}, translate: {x: 0, y: 0}, scale: 1 } }, methods: { handleScroll(e) { if(this.isHover) { let speed = e.wheelDelta/120 if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) { this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){ this.scale+=0.04*speed this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` } } }, dragMousedown() { this.moveStart.x = event.clientX this.moveStart.y = event.clientY this.isMousedown = true }, dragMousemove() { if(this.isMousedown) { this.translate.x += (event.clientX - this.moveStart.x) / this.scale this.translate.y += (event.clientY - this.moveStart.y) / this.scale this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)` this.moveStart.x = event.clientX this.moveStart.y = event.clientY } } }, mounted() { window.addEventListener('mousewheel',this.handleScroll,false) }}</script><style lang="scss" scoped>.drag-outer { width: 100%; height: 100%; overflow: hidden; display: flex; justify-content: center; align-items: center; .drag-inner { transform-origin: center center; display: flex; justify-content: center; align-items: center; cursor: move; user-select: none; >* { -webkit-user-drag: none; user-drag: none; } }}</style>
在home.vue文件使用:点击体验
<template> <div class="home"> <ElementDrag> <img src="https://img0.baidu.com/it/u=937276518,3474029246&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"> </ElementDrag> </div></template><script>import ElementDrag from '@/components/ElementDrag'export default { name: 'Home', components: { ElementDrag }}</script><style scoped>.home { width: 100vw; height: 100vh;} </style>
为什么要使用Vue
Vue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以创建可维护性和可测试性更强的代码库,Vue允许可以将一个网页分割成可复用的组件,每个组件都包含属于自己的HTML、CSS、JavaScript,以用来渲染网页中相应的地方,所以越来越多的前端开发者使用vue。
关于怎么利用vue组件实现图片的拖拽和缩放功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。