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事件,写了个拖动,发现只能慢慢拖动才行,鼠标只要移动快了,就失效,不能拖动了: 搞了半天在,总算解决了,但是问题的深层原理还没搞清楚,知道的大侠可以留言分享, ...
随机推荐
- [shell] shell echo打印换行的方法
echo要支持同C语言一样的\转义功能,只需要加上参数-e,如下所示: echo -e hello \n echo \n
- java线程基础巩固---采用多线程方式模拟银行排队叫号以及Runnable接口存在的必要性
采用多线程模拟银行排队叫号: 关于银行拿排队号去叫号的过程我想不必过多解释了,就是有几个业务窗口,并行的处理业务,每处里完一个人,则会叫下一个排队的号去处理业务,一个人是不会被多个窗口工作人员叫号的, ...
- django.core.exceptions.ImproperlyConfigured: The included URLconf 's9luffycity.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused
出现问题: $ python manage.py runserver 启动项目报错时候 raise ImproperlyConfigured(msg.format(name=self.urlconf_ ...
- 部署lnmp
装包 1.安装依赖包 yum - y install gcc openssl-devel pcre-devel zlib-devel 2.解源码包 .tar.gz 3.切换到解压缩后的目录,配置参数 ...
- MFC 线程的创建,线程函数在类内、类外
[线程的创建] AfxBeginThread(类外的线程函数,NULL); AfxBeginThread(类内的线程函数,(LPVOID)this); [类外线程函数] UINT 函数名(LPVOID ...
- has(expr|ele)保留包含特定后代的元素,去掉那些不含有指定后代的元素。
has(expr|ele) 概述 保留包含特定后代的元素,去掉那些不含有指定后代的元素.大理石平台等级 .has()方法将会从给定的jQuery对象中重新创建一组匹配的对象.提供的选择器会一一测试原先 ...
- learning armbian steps(9) ----- armbian 源码分析(四)
在上一节的分析当中,我们知道是通过对话框来选择到底编译的是哪块板子,基于什么样的配置. 接下来我们来拿一个实例来分析一下具体的案例,我们会选中如下所示的版本 iotx-3 AM335X 1Gb SoC ...
- vector 与 array
vector STL中的模板数组(在堆中分配内存空间,通过new delete管理内存) 使用包涵头文件#include <vector> vector<ElmentTpye> ...
- javascript数据结构之顺序表
关于线性表的概念这里就不赘述了,可以自行百度和查阅资料,线性表按照存储(物理)结构分为顺序存储和链式存储,每种存储方式的不同决定了它的实现代码是不同的: 顺序存储的特点就是在内存中选一块连续的地址空间 ...
- sql到python正则
import urllib.requestimport re,timeresult=[]for i in range(100): urls ="http://xxx.com/-1%20 ...