Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법
몇 가지 유용한 도구 추천
var-conv는 VSCode IDE에 적합한 코드 변수 이름을 위한 빠른 변환 도구입니다
generator-vite-plugin을 사용하면 Vite 플러그인 템플릿 프로젝트를 빠르게 생성할 수 있습니다
-
generator -babel-plugin Babel 플러그인 템플릿 프로젝트를 빠르게 생성
요점을 살펴보겠습니다.
요소 드래그는 일반적인 프런트엔드 학습 사례로, JavaScript 이벤트에 대한 어느 정도 이해가 필요합니다. 최근 작업에서는 이 내용을 다시 선택하여 Vue3과 같은 선언적 프로그래밍 스타일 프레임워크에서 요소를 한 번 드래그하여 명확하게 설명했습니다.
PS: Vue3 템플릿 전역 스타일의 중앙 속성은 실험적 간섭을 일으킬 수 있으므로 주의하세요! ! !
요소의 위치와 이동
요소 드래그를 구현할 때 mouse
事件,在 mouse
事件的回调函数中可以得到当前事件发生时元素的位置,对应的属性是 MouseEvent
中的 clientX
和 clientY
,我们后续将通过读取这两个属性来实时更新元素的位置。
元素的移动推荐优先使用 transform
中的 translate
实现,相比于修改元素的 top
、left
属性来说不会造成元素布局的改变,避免了回流和重绘造成的性能影响。
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, })
PS:当原点是页面左上角时在图中的1号点表示 originalPosition
或 elementPosition
,2号点表示指针按下时的坐标,当原点是1号点时在图中的2号点表示 mousedownOffset
;
注册 mousedown 事件
在实现元素拖拽时,仅需要给被拖拽的元素添加 mousedown
事件即可,监听事件使用完后记得要清楚掉,成对出现的习惯一定要养成。
如果你把 mousemove
和 mouseup
都添加到被拖拽的元素上,你会发现有脱离控制的现象发生。
在页面加载完成后首先要重置一下被拖拽元素的默认位置,并增加 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
添加 mousemove
和 mouseup
事件:
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="{ 'transition-duration': '0.1s', transform: `translate(${elementPosition.x}px, ${elementPosition.y}px)` }"> </div>
mouse
이벤트의 콜백 함수에서 요소의 위치를 얻을 수 있습니다. 현재 이벤트가 발생하면 MouseEvent의 clientX 및
🎜 세 개의 좌표 세트를 정의합니다. 🎜🎜🎜 각각 요소의 초기 위치(🎜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🎜
🎜🎜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🎜🎜🎜
.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🎜rrreee🎜🎜🎜
위 내용은 Vue3을 사용하여 우아한 요소 드래그 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











vue3+vite:src는 require를 사용하여 이미지를 동적으로 가져오고 vue3+vite는 여러 이미지를 동적으로 가져옵니다. vue3을 사용하는 경우 require는 이미지를 사용할 수 없습니다. imgUrl:require(' .../assets/test.png') 와 같은 vue2는 typescript가 require를 지원하지 않기 때문에 가져오므로 이를 해결하는 방법은 다음과 같습니다. waitimport를 사용합니다.

tinymce는 완전한 기능을 갖춘 리치 텍스트 편집기 플러그인이지만,tinymce를 vue에 도입하는 것은 다른 Vue 리치 텍스트 플러그인만큼 원활하지 않습니다.tinymce 자체는 Vue에 적합하지 않으며 @tinymce/tinymce-vue를 도입해야 합니다. 외국 서식 있는 텍스트 플러그인이며 중국어 버전을 통과하지 못했습니다. 공식 웹사이트에서 번역 패키지를 다운로드해야 합니다(방화벽을 우회해야 할 수도 있음). 1. 관련 종속성을 설치합니다. npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2. 중국어 패키지를 다운로드합니다. 3. 프로젝트 공용 폴더에 스킨과 중국어 패키지를 새로 만들고 다운로드합니다.

페이지를 부분적으로 새로 고치려면 로컬 구성 요소(dom)의 다시 렌더링만 구현하면 됩니다. Vue에서 이 효과를 얻는 가장 쉬운 방법은 v-if 지시어를 사용하는 것입니다. Vue2에서는 v-if 명령을 사용하여 로컬 DOM을 다시 렌더링하는 것 외에도 새 빈 구성 요소를 만들 수도 있습니다. 로컬 페이지를 새로 고쳐야 할 경우 이 빈 구성 요소 페이지로 점프한 다음 다시 돌아올 수 있습니다. 빈 원본 페이지의 beforeRouteEnter 가드. 아래 그림과 같이 Vue3.X에서 새로 고침 버튼을 클릭하여 빨간색 상자 안에 DOM을 다시 로드하고 해당 로딩 상태를 표시하는 방법입니다. Vue3.X의 scriptsetup 구문에 있는 구성 요소의 가드에는

Vue로 블로그 프론트엔드를 구현하려면 마크다운 파싱을 구현해야 합니다. 코드가 있는 경우 코드 하이라이팅을 구현해야 합니다. markdown-it, vue-markdown-loader,marked,vue-markdown 등과 같은 Vue용 마크다운 구문 분석 라이브러리가 많이 있습니다. 이 라이브러리는 모두 매우 유사합니다. 여기서는 Marked가 사용되었고, 코드 하이라이팅 라이브러리로 하이라이트.js가 사용되었습니다. 구체적인 구현 단계는 다음과 같습니다. 1. 종속 라이브러리를 설치합니다. vue 프로젝트에서 명령 창을 열고 다음 명령 npminstallmarked-save//marked를 입력하여 markdown을 htmlnpmins로 변환합니다.

vue3 프로젝트가 패키징되어 서버에 게시되면 액세스 페이지에 공백 1이 표시됩니다. vue.config.js 파일의 publicPath는 다음과 같이 처리됩니다. const{defineConfig}=require('@vue/cli-service') module.exports=defineConfig({publicPath :process.env.NODE_ENV==='생산'?'./':'/&

최종 효과는 VueCropper 컴포넌트 Yarnaddvue-cropper@next를 설치하는 것입니다. 위의 설치 값은 Vue2이거나 다른 방법을 사용하여 참조하려는 경우 공식 npm 주소: 공식 튜토리얼을 방문하세요. 컴포넌트에서 참조하고 사용하는 것도 매우 간단합니다. 여기서는 해당 컴포넌트와 해당 스타일 파일을 소개하기만 하면 됩니다. 여기서는 import{userInfoByRequest}from'../js/api만 소개하면 됩니다. 내 구성 요소 파일에서 import{VueCropper}from'vue-cropper&

vue3+ts+axios+pinia는 무의미한 새로 고침을 실현합니다. 1. 먼저 프로젝트에서 aiXos 및 pinianpmipinia를 다운로드합니다--savenpminstallaxios--save2. AxiosResponse}from"axios";importaxiosfrom'axios';import{ElMess

머리말 Vue든 React든, 여러 개의 반복되는 코드를 접하게 되면, 파일을 중복된 코드 덩어리로 채우는 대신, 이러한 코드를 어떻게 재사용할 수 있을지 고민해 보겠습니다. 실제로 vue와 React 모두 컴포넌트를 추출하여 재사용할 수 있지만, 작은 코드 조각이 발견되어 다른 파일을 추출하고 싶지 않은 경우, 이에 비해 React는 동일한에서 사용할 수 있습니다. 파일에서 해당 위젯을 선언합니다. 또는 다음과 같은 renderfunction을 통해 구현합니다. constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(
