在vue项目中使用了局部自定义指令,然后需要在该指令中操作data中的数据。
在vue项目中,局部增加了拖动指令,由于拖动的dom新增节点或者刷新数据,使拖动的dom复位了。
新增dom节点或者更新dom数据,导致初始化了整个dom,所以样式也初始化了。
由于js直接更改class中的属性,十分困难,所以直接使用vue中data存储拖动时的样式,这样即便dom初始化,也不会导致dom复位(即不会导致样式初始化)。
使用directives中的vnode参数中的context属性,来获取methods中的方法。
代码如下:
1.html部分
<div
v-drag
style={{
left: `${this.left}`,
top: `${this.top}`,
}}
></div>
2.js部分
export default {
directives: {
// 自定义拖拽指令,先声明这个指令
drag(el, binding, vnode) {
// 可就在里写指令的js代码
const oDiv = el; // 当前元素
oDiv.onmousedown = (e) => {
// 鼠标按下时的鼠标所在的X,Y坐标
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - oDiv.offsetLeft;
const disY = e.clientY - oDiv.offsetTop;
document.onmousemove = (e) => {
// 通过事件委托,计算移动的距离
// 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
const l = e.clientX - disX;
const t = e.clientY - disY;
// 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
// oDiv.style.left = l + "px";
// oDiv.style.top = t + "px";
// 换为此种方法,防止点击弹框保存,或者新增分支等情况时,复位
vnode.context.setLeftTop(l + "px", t + "px");
};
document.onmouseup = (e) => {
// 鼠标抬起,清空之前所在的位置,新拖拽的位置已生成并赋值
document.onmousemove = null;
document.onmouseup = null;
};
// return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
return false;
};
},
},
data() {
return {
left: "10%",
top: "20%",
};
},
methods: {
//自定义指令通过此设置top和left
setLeftTop(left, top) {
this.left = left;
this.top = top;
},
}
}