vue指令实现拖动的高级写法
不熟悉vue自定义指令看这里: https://cn.vuejs.org/v2/guide/custom-directive.html
vue指令实现拖动方法很方便也挺简单,但是网上大部分的教程代码,一般都是把代码全部写一个方法里面,代码不够美观,代码逻辑也不太清晰,不推荐这种写法,比如下面这样:
Vue.directives: {
drag: {
// 使用bind会有可能没有渲染完成
inserted: function(el, binding, vnode) {
const _el = el; //获取当前元素
const ref = vnode.context.$refs[binding.value]; // 判断基于移动的是哪一个盒子
const masterNode = ref ? ref : document; // 用于绑定事件
const masterBody = ref ? ref : document.body; // 用于获取高和宽
const mgl = _el.offsetLeft;
const mgt = _el.offsetTop;
const maxWidth = masterBody.clientWidth;
const maxHeight = masterBody.clientHeight;
const elWidth = _el.clientWidth;
const elHeight = _el.clientHeight;
let positionX = 0,
positionY = 0;
_el.onmousedown = e => {
//算出鼠标相对元素的位置,加上的值是margin的值
let disX = e.clientX - _el.offsetLeft + mgl;
let disY = e.clientY - _el.offsetTop + mgt;
masterNode.onmousemove = e => {
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
let top = e.clientY - disY;
// 绑定的值不能滑出基于盒子的范围
left < 0 && (left = 0);
left > (maxWidth - elWidth - mgl) && (left = maxWidth - elWidth - mgl);
top < 0 && (top = 0);
top > (maxHeight - elHeight - mgt) && (top = maxHeight - elHeight - mgt);
//绑定元素位置到positionX和positionY上面
positionX = top;
positionY = left;
//移动当前元素
_el.style.left = left + "px";
_el.style.top = top + "px";
};
// 这里是鼠标超出基于盒子范围之后再松开,会监听不到
document.onmouseup = e => {
masterNode.onmousemove = null;
document.onmouseup = null;
};
};
}
}
}
这里介绍一种比较方美观,逻辑清晰的写法,代码如下:
Vue.directive('drag', {
bind (el, binding) {
el.style.cursor = 'move'
el.style.position = 'fixed'
el.mousedownPoint = {
x: 0,
y: 0
}
// bind 改变函数内部 this 指向,让 this 指向 el
// el.handleMouseup, el.handleMousemove, el.handleMousedown 这三个可以是其他的全局变量
el.handleMouseup = handleMouseup.bind(el)
el.handleMousemove = handleMousemove.bind(el)
el.handleMousedown = handleMousedown.bind(el)
el.addEventListener('mousedown', el.handleMousedown)
document.body.addEventListener('mouseup', el.handleMouseup)
document.body.addEventListener('mousemove', el.handleMousemove)
},
unbind (el) {
document.body.removeEventListener('mouseup', el.handleMouseup)
document.body.removeEventListener('mousemove', el.handleMousemove)
}
});
const handleMousedown = function (e) {
// 这里的this被bind改变了,是el
// 这里的e是 MouseEvent 对象
const initialPosition = this.getBoundingClientRect()
this.style.width = initialPosition.width + 'px'
this.position = {
left: initialPosition.left,
top: initialPosition.top
}
this.readyToMove = true
this.mousedownPoint.x = e.screenX
this.mousedownPoint.y = e.screenY
}
const handleMousemove = function (e) {
if (!this.readyToMove) return false
const position = this.position
position.left = position.left + e.screenX - this.mousedownPoint.x
position.top = position.top + e.screenY - this.mousedownPoint.y
this.mousedownPoint.x = e.screenX
this.mousedownPoint.y = e.screenY
this.style.left = position.left + 'px'
this.style.transform = 'none'
this.style.marginLeft = 0
this.style.marginTop = 0
this.style.top = position.top + 'px'
this.style.bottom = 'auto'
this.style.right = 'auto'
}
const handleMouseup = function (e) {
this.readyToMove = false
}
这种写法主要利用了bind的特性,回一个新的函数,并且这个函数的 this 已经被改成我们想要的 this, 推荐这种写法。
vue指令实现拖动的高级写法的更多相关文章
- 一个能拖动,能调整大小,能更新bind值的vue指令-vuedragx
一. 背景说明 开发一个可自定义组件化门户配置页面,期间采用了vue框架作为前端视图引擎,作为一个刚入手vue的萌新,开发第一个功能就遇到了拦路虎.需要一个拖动并且可改变大小的容器盒子.当时查看vue ...
- 自定义类似于Jquery UI Selectable 的Vue指令v-selectable
话不多说,先看效果. 其实就是一个可以按住鼠标进行一个区域内条目选择的功能,相信用过Jquery UI 的都知道这是selectable的功能,然而我们如果用Vue开发的话没有类似的插件,当然你仍然可 ...
- vue指令用法
vue指令 指令式带有 v- 前缀的特殊特性v-text和v-html都属于指令将数据和dom做关联,当表达式的值改变时,响应式地作用在视图 解决大胡子语法闪烁案例 [v-cloak] { dispa ...
- Vue框架(一)——Vue导读、Vue实例(挂载点el、数据data、过滤器filters)、Vue指令(文本指令v-text、事件指令v-on、属性指令v-bind、表单指令v-model)
Vue导读 1.Vue框架 vue是可以独立完成前后端分离式web项目的js框架 三大主流框架之一:Angular.React.Vue vue:结合其他框架优点.轻量级.中文API.数据驱动.双向绑定 ...
- Vue学习笔记【4】——Vue指令之v-on
Vue指令之v-on v-on指令介绍 直接使用指令v-on 使用简化指令@ 绑定事件代码:@事件名="methods中的方法名称" <!DOCTYPE html> & ...
- vue2,vue指令和选项
vue特点 mvvm框架 响应式(声明式) 组件化(支持自定义组件) 丰富的指令(Dom功能的抽象) 基于选项(template,data,computed,watch,methods) vue文档集 ...
- Vue指令总结---小白同学必看
今天主要复习一下我们最熟悉vue指令,想要代码撸得快,就要多看书,多看看官方的文档和学习指令,学习编程是一个非常享受的过程,尤其是你不断地去解决问题,获得一项技能,实现薪水的上涨.进行Vue的指令烹饪 ...
- 使用Vue.js制作仿Metronic高级表格(一)静态设计
Metronic高级表格是Metonic框架中自行实现的表格,其底层是Datatables.本教程将主要使用Vue实现交互部分,使用Bootstrap做样式库.jQuery做部分用户交互(弹窗). 使 ...
- vue+mousemove实现拖动,鼠标移动过快拖动就失效
今天用vue+原生js的mousemove事件,写了个拖动,发现只能慢慢拖动才行,鼠标只要移动快了,就失效,不能拖动了: 搞了半天在,总算解决了,但是问题的深层原理还没搞清楚,知道的大侠可以留言分享, ...
随机推荐
- CAFFE(二):Ubuntu 下安装OpenCv 3.4.1
一步:进入OpenCv官网 选择 3.4.1 版本的 source , 下载 opencv-3.4.1.zip ,如下图选择Sources下载 解压缩到home目录.并执行如下代码: { cd ~/o ...
- systemctl可以实现nginx进程挂了之后自动重新启动
接 2018年7月31日的那篇: vim /lib/systemd/system/nginx.service [Service]Restart=alwaysRestartSec=1Type=forki ...
- Hive启动报错Terminal initialization failed; falling back to unsupported java.lang.Incomp
这个报错需要删除hadoop目录下,需要删除下面目录下的文件,重启hadoop和hive即可 $HADOOP_HOME/share/hadoop/yarn/lib/jline-0.9.94.jar
- C语言例题
1.连接两个字符串 将两个字符串连接,不要用stract函数 2.求矩阵外围元素之和 求3行3列矩阵的外围元素之和. 3.求矩阵主对角线和副对角线元素之和 求5行5列矩阵的主对角线和副对角线元素之和. ...
- HDU 6046 - hash | 2017 Multi-University Training Contest 2
思路来自题解和一些博客 最麻烦的是样例没啥用- - /* HDU 6046 - hash [ hash,鸽巢 ] | 2017 Multi-University Training Contest 2 ...
- vue中使用v-chart改变柱状图颜色以及X轴Y轴的文字颜色和大小以及标题
1.html部分 <ve-histogram :tooltip-visible="true" :x-axis="xAxis" :y-axis=" ...
- 解决ubuntu的screen已经处于Attached状态,无法再打开窗口
Attached表示该窗口已经被上一登录用户使用,需要重新登录 1. 先查询窗口id screen -ls 3606.node (11/26/2019 07:31:49 PM) (Attached) ...
- Codeforces工具总结
本总结针对Linux用户,由于笔者一直使用Ubuntu系统打Codeforces 打Codeforcecs,想精确能力,打出究极罚时,可以考虑以下套餐 套餐一 vim选手 使用vim + fish + ...
- 牛客练习赛52 B题【树状数组维护区间和{查询区间和,如果区间元素重复出现则计数一次}】补题ing
[题目] 查询区间和,如果区间元素重复出现则计数一次. 链接:https://ac.nowcoder.com/acm/contest/1084/B [题解] 将询问按r排序,维护每个数最后出现的位置, ...
- Linq to XML - C#生成XML
1.System.Xml.XmlDocument XML file转成字符串 string path3 = @"C:\Users\test.xml"; XmlDocument ...