Vue使用自定義指令實現(xiàn)拖拽行為實例分析
本文實例講述了Vue使用自定義指令實現(xiàn)拖拽行為。分享給大家供大家參考,具體如下:
需求
通過自定義指令的方式實現(xiàn)拖拽效果,預(yù)期的使用方式為:
<div style="background: #f00; width: 200px; height: 200px;" v-drag> XXXX </div>
更重要的一個需求點:
- 拖拽元素內(nèi)部的子元素可以自行阻止拖拽行為
比如:
<div style="background: #f00; width: 200px; height: 200px;" v-drag> <el-button @mousedown.native.stop>test</el-button> </div>
曾經(jīng)使用過vue-resizable,由于該組件是通過事件捕獲的方式實現(xiàn)的,拖拽元素的子元素也會觸發(fā)拖拽行為,不符合開發(fā)需求,所以自行實現(xiàn)了拖拽指令,相關(guān)源碼如下。
無任何依賴,復(fù)制即可使用
源碼
/**
* @file 自定義拖拽命令
*/
import Vue from 'vue';
const Drag = {
install(Vue: any) {
// 如需禁止拖拽元素內(nèi)部某些元素觸發(fā)拖拽,在內(nèi)部不可觸發(fā)拖拽元素上添加@mousedown.native.stop即可
Vue.directive('drag', {
bind(el: any) {
el.style.position = 'absolute';
el.style.zIndex = el.style.zIndex || '3000';
},
inserted(el: any) {
// 設(shè)置元素初始位置
const boundingClientRect = el.getBoundingClientRect();
el.style.left = boundingClientRect.x + 'px';
el.style.top = boundingClientRect.y + 'px';
// 將拖拽元素置于body子元素,防止被relative的父元素遮擋
document.body.appendChild(el);
let originX: number;
let originY: number;
const mouseDownHandler = (evt: MouseEvent) => {
originX = evt.clientX - el.offsetLeft;
originY = evt.clientY - el.offsetTop;
el.style.cursor = 'pointer';
};
const mouseMoveHandler = (evt: MouseEvent) => {
if (evt.buttons === 1 && originX && originY) {
el.style.left = evt.clientX - originX + 'px';
el.style.top = evt.clientY - originY + 'px';
}
};
const mouseUpHandler = () => {
el.style.cursor = 'default';
};
el.addEventListener('mousedown', mouseDownHandler);
el.addEventListener('mousemove', mouseMoveHandler);
el.addEventListener('mouseup', mouseUpHandler);
el.__mouseDownHandler__ = mouseDownHandler;
el.__mouseMoveHandler__ = mouseMoveHandler;
el.__mouseUpHandler__ = mouseUpHandler;
},
unbind(el: any) {
el.removeEventListener('mousedown', el.__mouseDownHandler__);
el.removeEventListener('mousemove', el.__mouseMoveHandler__);
el.removeEventListener('mouseup', el.__mouseUpHandler__);
// 當(dāng)父組件銷毀觸發(fā)unbind的時候需要手動刪除這個節(jié)點,不然會一直存留在body中
el.parentNode.removeChild(el);
}
});
}
};
Vue.use(Drag);
export default Drag;
希望本文所述對大家vue.js程序設(shè)計有所幫助。
相關(guān)文章
vue基于element-china-area-data插件實現(xiàn)省市區(qū)聯(lián)動
省市區(qū)聯(lián)動在日常開發(fā)中用的非常多,本文就介紹一下vue基于element-china-area-data插件實現(xiàn)省市區(qū)聯(lián)動,具有一定的參考價值,感興趣的可以了解一下2022-04-04
基于Vue3.0開發(fā)輕量級手機端彈框組件V3Popup的場景分析
這篇文章主要介紹了基于Vue3.0開發(fā)輕量級手機端彈框組件V3Popup,本文通過場景分析給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
vue里面v-bind和Props 利用props綁定動態(tài)數(shù)據(jù)的方法
今天小編就為大家分享一篇vue里面v-bind和Props 利用props綁定動態(tài)數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Vue3.0之引入Element-plus ui樣式的兩種方法
本文主要介紹了Vue3.0之引入Element-plus ui樣式的兩種方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局
這篇文章主要介紹了Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局,工作中難免遇到需要對頁面布局進行拖拽然后改變布局,保存布局,下面文章就圍繞Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局的相關(guān)資料展開詳細(xì)內(nèi)容,需要的朋友可以參考一下2021-11-11
vue3項目打包成apk(android)詳細(xì)圖文教程
Vue本身是一個構(gòu)建用戶界面的漸進式框架,不能直接打包成APK文件,但是你可以使用工具將Vue應(yīng)用打包成一個可以在Android設(shè)備上安裝的APK文件,這篇文章主要給大家介紹了關(guān)于vue3項目打包成apk(android)的相關(guān)資料,需要的朋友可以參考下2024-05-05

