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項目中created()被調(diào)用多次的踩坑實戰(zhàn)
在vue項目中我在created中調(diào)用了兩次get數(shù)據(jù)請求,所以下面這篇文章主要給大家介紹了關(guān)于vue項目中created()被調(diào)用多次的踩坑實戰(zhàn),需要的朋友可以參考下2023-03-03
MAC+PyCharm+Flask+Vue.js搭建系統(tǒng)
最近新做了個項目,使用的是MAC+PyCharm+Flask+Vue.js搭建系統(tǒng),本文就來分享一下搭建步驟,感興趣的可以了解一下2021-05-05
解決element ui select下拉框不回顯數(shù)據(jù)問題的解決
這篇文章主要介紹了解決element ui select下拉框不回顯數(shù)據(jù)問題的解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
在vue3中使用el-tree-select實現(xiàn)樹形下拉選擇器效果
el-tree-select是一個含有下拉菜單的樹形選擇器,結(jié)合了?el-tree?和?el-select?兩個組件的功能,這篇文章主要介紹了在vue3中使用el-tree-select做一個樹形下拉選擇器,需要的朋友可以參考下2024-03-03

