>웹 프론트엔드 >View.js >Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법

Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법

WBOY
WBOY앞으로
2023-05-13 18:46:061840검색

몇 가지 유용한 도구 추천

  • var-conv는 VSCode IDE에 적합한 코드 변수 이름을 위한 빠른 변환 도구입니다

  • generator-vite-plugin을 사용하면 Vite 플러그인 템플릿 프로젝트를 빠르게 생성할 수 있습니다

  • generator -babel-plugin Babel 플러그인 템플릿 프로젝트를 빠르게 생성

요점을 살펴보겠습니다.

요소 드래그는 일반적인 프런트엔드 학습 사례로, JavaScript 이벤트에 대한 어느 정도 이해가 필요합니다. 최근 작업에서는 이 내용을 다시 선택하여 Vue3과 같은 선언적 프로그래밍 스타일 프레임워크에서 요소를 한 번 드래그하여 명확하게 설명했습니다.

PS: Vue3 템플릿 전역 스타일의 중앙 속성은 실험적 간섭을 일으킬 수 있으므로 주의하세요! ! !

요소의 위치와 이동

요소 드래그를 구현할 때 mouse 事件,在 mouse 事件的回调函数中可以得到当前事件发生时元素的位置,对应的属性是 MouseEvent 中的 clientXclientY,我们后续将通过读取这两个属性来实时更新元素的位置。

元素的移动推荐优先使用 transform 中的 translate 实现,相比于修改元素的 topleft 属性来说不会造成元素布局的改变,避免了回流和重绘造成的性能影响。

PS:在 MDN 有一份关于translate的使用和体验,可以感受一下。

定义三组坐标

分别定义用来记录元素初始位置的一组坐标(originalPosition)、元素被按下时指针在元素上的坐标(mousedownOffset)和元素在移动时实时更新的一组坐标(elementPosition)。

记录元素初始位置的坐标,原点位于页面左上角,用来在初始化和被拖拽结束后还原被拖拽元素的位置,固定值不发生变化:

const originalPosition = reactive({
  x: 10,
  y: 10,
})

元素被按下时指针在元素上的坐标,原点位于被拖拽元素的左上角,通过按下时指针的坐标 - 元素初始的偏移位置得到:

const mousedownOffset = reactive({
  x: 0,
  y: 0,
})

元素在移动时实时更新的坐标,原点位于页面左上角,初始值应该同 originalPosition ,在 mousemove 事件发生时,通过指针的实时坐标 - mousedownOffset 得到:

const elementPosition = reactive({
  x: 0,
  y: 0,
})

Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법

PS:当原点是页面左上角时在图中的1号点表示 originalPositionelementPosition,2号点表示指针按下时的坐标,当原点是1号点时在图中的2号点表示 mousedownOffset

注册 mousedown 事件

在实现元素拖拽时,仅需要给被拖拽的元素添加 mousedown 事件即可,监听事件使用完后记得要清楚掉,成对出现的习惯一定要养成。

如果你把 mousemovemouseup 都添加到被拖拽的元素上,你会发现有脱离控制的现象发生。

在页面加载完成后首先要重置一下被拖拽元素的默认位置,并增加 mousedown 事件,在组件卸载后删除 mousedown 事件:

const restore = () => {
  elementPosition.x = originalPosition.x;
  elementPosition.y = originalPosition.y;
}

onMounted(() => {
  restore();
  floatButton.value.addEventListener('mousedown', onMousedown, true);
})

onUnmounted(() => {
  floatButton.value.removeEventListener('mousedown', onMousedown, true);
})

实现拖拽的核心

选择 Vuejs 的原因就是因为其是 MVVM 型框架,我们关注点在声明上,内部的运转机制有框架负责,所以在下面的事件处理上就只需要在对应的事件中去更新一开始声明的三组坐标就可以了。

onMousedown 时,通过指针所在的坐标 - 被拖拽元素初始位置的坐标得到指针此时在被拖拽元素上的坐标,onMousedown 时要为 document 添加 mousemovemouseup 事件:

const onMousedown = (event: MouseEvent) => {
  event.stopPropagation();
  
  mousedownOffset.x = event.clientX - originalPosition.x;
  mousedownOffset.y = event.clientY - originalPosition.y;
  
  document.addEventListener('mousemove', onMousemove, true);
  document.addEventListener('mouseup', onMouseup, true);
}

onMousemove时,通过指针所在的坐标 - 指针在被拖拽元素上的位置得到被拖拽元素左上角距离页面左上角的距离,并更新到 elementPosition

const onMousemove = (event: MouseEvent) => {
  event.stopPropagation();
  
  elementPosition.x = event.clientX - mousedownOffset.x;
  elementPosition.y = event.clientY - mousedownOffset.y;
}

onMouseup时,主要做的就是为 document 移除在 onMousemove 时注册的两个事件,要注意的是移除的事件要是同一个事件,也就是引用一致的事件,推荐将对应的处理事件赋值给一个变量使用,最后可以在拖拽结束后还原被拖拽元素的位置:

const onMouseup = (event: MouseEvent) => {
  event.stopPropagation();
  document.removeEventListener('mousemove', onMousemove, true);
  document.removeEventListener('mouseup', onMouseup, true);
  restore();
}

补充其它部分代码和演示

<div 
 ref="floatButton"
 class="float-button"
 :style="{
    &#39;transition-duration&#39;: &#39;0.1s&#39;,
    transform: `translate(${elementPosition.x}px, ${elementPosition.y}px)`
  }">
</div>
mouse 이벤트를 사용합니다. mouse 이벤트의 콜백 함수에서 요소의 위치를 ​​얻을 수 있습니다. 현재 이벤트가 발생하면

MouseEvent의 Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법clientX 및

clientY 속성에 해당합니다. 나중에 이 두 속성을 읽어 요소의 위치를 ​​실시간으로 업데이트하겠습니다. 🎜transform에서 🎜translate 구현을 사용하여 🎜🎜 요소를 먼저 이동하는 것이 요소의 🎜top 및 🎜left 속성을 ​​수정하는 것과 비교하면, 레이아웃을 변경하면 리플로우 및 다시 그리기로 인한 성능 영향을 피할 수 있습니다. 🎜🎜PS: MDN에 번역의 사용과 경험에 대한 기사가 있는데, 느끼실 수 있습니다. 🎜

🎜 세 개의 좌표 세트를 정의합니다. 🎜🎜🎜 각각 요소의 초기 위치(🎜originalPosition)를 기록하는 데 사용되는 좌표 세트를 정의합니다. 요소를 누를 때의 요소 요소가 움직일 때 실시간으로 업데이트되는 요소의 좌표(🎜mousedownOffset)와 좌표 집합(🎜elementPosition)입니다. 🎜🎜요소의 초기 위치 좌표를 기록합니다. 원점은 페이지의 왼쪽 상단에 있습니다. 초기화 및 드래그 후 드래그된 요소의 위치를 ​​복원하는 데 사용됩니다. 🎜
.float-button {
  position: absolute;
  width: 42px;
  height: 42px;
  background: red;
  border-radius: 5px;
  user-select: none;
  background-image: url(../assets/taobao.svg);
  background-size: cover;
}
🎜요소를 누르면 포인터가 요소 위에 있습니다. 의 좌표는 원점은 드래그된 요소의 왼쪽 상단에 위치하며, 눌렀을 때 포인터의 좌표로 구합니다. - 요소의 초기 오프셋 위치 요소: 🎜rrreee🎜요소가 이동할 때 실시간으로 업데이트되는 좌표, 원점은 페이지 왼쪽 상단에 위치하며, 초기값은 🎜mousemove과 동일해야 합니다. /code> 이벤트가 발생하면 포인터의 실시간 좌표 - 🎜mousedownOffset가 획득됩니다: 🎜rrreee🎜Vue3를 사용하여 우아한 요소 드래그 기능을 구현하는 방법🎜🎜PS: 원점이 페이지의 왼쪽 상단이면 그림의 1번 지점이 🎜originalPosition을 나타냅니다. 또는 🎜elementPosition. 포인트 2는 포인터를 눌렀을 때의 좌표를 나타냅니다. 원점이 포인트 1일 때 그림의 포인트 2는 🎜mousedownOffset을 나타냅니다. heading-6">🎜mousedown 이벤트 등록🎜🎜🎜요소 드래그를 구현할 때 드래그된 요소에 🎜mousedown 이벤트만 추가하면 됩니다. 이벤트를 사용한 후 청취하는 것을 잊지 마세요. 명확하게 하려면 습관 쌍으로 나타나는 방식이 개발되어야 합니다. 🎜🎜드래그된 요소에 🎜mousemove와 🎜mouseup을 모두 추가하면 제어 불능이 발생하는 것을 확인할 수 있습니다. 🎜🎜페이지가 로드된 후 먼저 드래그된 요소의 기본 위치를 재설정하고 🎜mousedown 이벤트를 추가하세요. 구성 요소가 언로드된 후 🎜mousedown 이벤트를 삭제하세요. 🎜rrreee

🎜드래그 앤 드롭 구현의 핵심🎜🎜🎜우리가 🎜Vuejs를 선택한 이유는 🎜MVVM 유형 프레임워크이기 때문입니다. 선언 내부 작동 메커니즘은 프레임워크에서 담당하므로 다음 이벤트 처리에서는 해당 이벤트의 시작 부분에 선언된 세 가지 좌표 세트만 업데이트하면 됩니다. 🎜🎜 🎜onMousedown에서는 드래그된 요소의 포인터 좌표를 포인터의 좌표, 즉 드래그된 요소의 초기 위치 좌표를 통해 얻습니다. 🎜document 🎜mousemove 및 🎜mouseup 이벤트 추가: 🎜rrreee🎜 🎜onMousemove일 때 포인터는 포인터 좌표(포인터의 위치)를 통해 드래그됩니다. 드래그된 요소의 왼쪽 상단과 페이지의 왼쪽 상단 사이의 거리이며 🎜elementPosition으로 업데이트되었습니다. 🎜rrreee🎜At 🎜onMouseup에서 해야 할 일은 다음과 같습니다. 🎜document 코드>에 대한 🎜onMousemove를 제거하려면 제거된 이벤트가 동일한 이벤트, 즉 동일한 참조를 가진 이벤트인 경우 해당 이벤트를 할당하는 것이 좋습니다. 이벤트를 변수로 처리하여 드래그가 완료된 후 복원할 수 있습니다. 드래그 요소의 위치: 🎜rrreee

🎜코드 및 데모의 다른 부분을 보충하세요. 🎜🎜rrreee🎜rrreee🎜🎜🎜

위 내용은 Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제