本文将介绍如何实现一个注册全局指令的插件,可以自动判断vue版本,并进行差异消除的处理。
本文示例源码:gitee 、github、npm地址,欢迎start哦。
前置介绍-出发点
最近写了个vue3的自定义指令,用来拖动元素。为了不影响元素的布局,选用了transform:translate()
变换,来实现拖动。实现并不难,思路大概是:
- 监听元素mousedown事件,点击时记录开始坐标。并监听元素mousemove事件。
- 当元素触发mousemove,实时获取鼠标坐标,并减去第一步记录的开始坐标,得到移动的距离。
- 得到了移动距离,实时更新到translate即可。
- 监听mouseup、mouseleave事件,移除mousemove还有自己的监听,收尾!
指令实现起来挺简单,考虑到目前vue3还没火到完全取代vue2,我想能不能让它在vue2也正常运行呢?
具体实现可跳转github查看哦,这里主要介绍如何实现兼容。
行动
实现一个兼容vue2、vue3的指令
准备:通过官网介绍,对比vue2和vue3实现自定义指令的异同:
- vue2、vue3中的自定义指令都是一个对象,对象里是各种钩子函数,形式上一致。
- 每个钩子接收的参数个数、位置,vue2、vue3几乎没有区别,只是第二个参数(一个对象)里有几个不常用属性的进行了破坏性更新,常用的没变。
- vue3中的钩子更多更精细,且覆盖了vue2的所有钩子,只是命名不一样(vue2的那几个也够用了)。
结论:
完全具有可行性!
只要将定义指令的对象,定义为一个模块,内部实现的逻辑只需要一份,只是导出vue3的指令对象的同时,再适配vue2,把钩子名换成vue2的命名方式,再导出一个对象即可。
基本实现:
-
先实现一下定义指令的对象:
// lite-move.js // 拖动处理函数 function moveAction(e) { /* e为事件对象,也可以通过this来访问dom元素 */ } // 元素插入dom时的钩子函数 const mounted = (el, binding) => { // moveAction内部要访问dom时,最好用this,而不是钩子提供的el,性能更好,耦合度低 el.addEventListener('mousedown', binding.value = moveAction) } // 父组件销毁时的钩子函数 const unmounted = (el, binding) => {