• 售前

  • 售后

热门帖子
入门百科

怎样使用vue自界说指令构建拖放插件

[复制链接]
caymkda949764 显示全部楼层 发表于 2021-10-26 13:31:16 |阅读模式 打印 上一主题 下一主题
我们都知道html5的拖放特性,利用它可以很方便的实现拖拽和放置功能,比如一些选择类操纵的利用场景,让用户去拖拽比鼠标点击更容易接受和明白。本日我们就利用这一特性,结合vue的自界说指令,来实现一个简朴但是实用的拖放插件。
为什么叫它插件?由于我们的目标不是开发一个vue组件,而是两个vue的自界说指令,而且最终会把这两个自界说指令封装到一个es6的class里,在实际项目中引入就可以很方便的利用了。
大部门的拖放利用场景都是把一些待选元素从A地区拖放到B地区。这里就涉及到两个概念,一个是可拖拽,一个是可放置,待选元素肯定是可以被拖拽的,而目标地区(容器)肯定是可以放置的。
如果我们开发一个可拖拽的vue组件,大概开发一个可放置的组件,那仅仅是这个组件可拖放,此时如果需求变动,又必要另外一个组件也支持拖放,那我们仍必要为另一个组件也编写拖放的代码。又大概其他项目也必要拖放功能了,我们也要重新开发。如许非常倒霉于维护和复用,而vue的自界说指令很好的帮我们办理了这个问题,我们只必要在组件(包罗普通的dom元素)上添加自界说指令,就可以使这个组件(元素)可拖放,如许就可以灵活的去利用了。
  1. 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
复制代码
综上,本文的目标必要完成两个自界说指令:
       
  • v-drag 使组件可拖拽   
  • v-drop 使组件可放置
目标已经很明白了,那就开始动手吧!由于我们要让这两个指令可在恣意组件上发挥作用,因此必要注册Vue全局指令。
  1. Vue.directive('drag', {
  2.    bind(el, binding, vnode){
  3.         //只调用一次,指令第一次绑定到元素时调用。
  4.         //在这里可以进行一次性的初始化设置。
  5.     }
  6. })
  7. Vue.directive('drop', {
  8.    bind(el, binding, vnode){
  9.         //
  10.     }
  11. })
复制代码
如果你的项目是vue-cli搭建的,你可以把这段代码写在main.js里vue初始化的上方。
我们先在drag指令的bind钩子里编写代码,bind只调用一次,而且是在指令第一次绑定到元素时调用,因此我们用了bind钩子。这个指令的目标是让组件(元素)可拖拽,以是我们设置el的draggable为true
  1. el.draggable = true;
  2. el.ondragstart = (event)=>{
  3.   event.dataTransfer.setData("Text", "your data...");
  4. }
复制代码
当元素被拖拽时,会先触发ondragstart事件,通常我们都会在这个事件里为event的dataTransfer设置拖拽数据,目标是当元素被放置时,目标容器可以获取拖拽过来的数据,如果拖放不能传递数据,那将是没故意义的。上面的代码调用dataTransfer的setData方法设置拖拽数据,setData的参数1表现数据范例,参数2表现要传递的数据。
很不幸,拖拽数据目前仅支持字符串,如果你想传递复杂对象,可以将数据序列化
接下来我们为drop指令的bind钩子编写代码,这个指令的目标是让组件(元素)可放置,因此我们必要为元素的ondragover(拖拽经过事件)、ondrop(放置事件)编写handler,这两个handler要阻止事件的默认活动。
  1. el.ondragover = (event)=>{
  2.   event.preventDefault(); //阻止默认行为
  3. }
  4. el.ondrop = (event)=>{
  5.   event.preventDefault();
  6.   let dragData = event.dataTransfer.getData('Text'); //获取拖拽数据
  7. }
复制代码
我们通过event.dataTransfer的getData方法可以获取到拖拽开始事件中设置的拖拽数据。
现在你就可以把这两个指令加到任何组件上了,加了v-drag的组件可以被拖动,加了v-drop的组件可以放置并汲取拖拽数据。
  1. <MyComponent v-drag></MyComponent>
  2. <MyContainer v-drop></MyContainer>
复制代码
新的问题来了,我们进行拖拽操纵是为了传递数据,然而传递数据的开始阶段,我们是在自界说指令drag的bind钩子里进行的,传递数据的汲取阶段,我们是在drop的bind钩子里进行的,那么,数据从哪儿来?到哪儿去?很显然,数据应该来自组件,也应该传递给另一个组件,否则我们把指令写到vue组件上就没有任何意义了。
幸亏自界说指令的钩子函数为我们提供了访问组件最简朴有效的方式:那就是钩子函数的第三个参数vnode,vnode有一个属性是componentInstance,这个componentInstance就是自界说指令的宿主:vue组件实例!
接下来就很容易了,我们只必要为添加了v-drag的组件界说一个获取拖拽数据的接口,为添加了v-drop的组件界说一个汲取拖拽数据的接口即可。固然vue组件并不支持接口的界说,但我们可以约定好这两个方法名,在组件的method中进行实现即可。
  1. //自定义组件内部
  2. methods:{
  3.   getDragData(){ //约定getDragData为获取组件拖拽数据的接口方法
  4.     return this.id; //假设这个组件被拖拽时,需要将id传递出去
  5.   }
  6.   setDragData(data){ //约定setDragData为组件接收拖拽数据的接口方法
  7.     this.appendNewChildById(data); //假设这个组件接收id来生成新元素
  8.   }
  9. }
复制代码
然后改写我们自界说指令设置和传递拖拽数据的代码:
  1. let dragValue = "";
  2. if(vnode.componentInstance.getDragData != undefined){
  3.   dragValue = vnode.componentInstance.getDragData();
  4. }
  5. event.dataTransfer.setData("Text", dragValue);
复制代码
v-drop指令中的ondrop事件
  1. let dragValue = event.dataTransfer.getData('Text');
  2. if(vnode.componentInstance.setDragData != undefined){
  3.   vnode.componentInstance.setDragData(dragValue);
  4. }
复制代码
我们在访问组件的接口方法时加了 if 判定,由于没有接口的束缚,组件大概并没有实现这些方法。
好啦,到这里我们已经完全实现了组件拖放的自界说指令,固然很简朴,但是很实用也很灵活,根本可以满足一样平常拖拽的需求,让我们总结一下整个流程吧!
       
  • 自界说全局指令 v-drag、v-drop   
  • 必要拖拽的组件实现获取数据的接口方法   
  • 必要放置的组件实现汲取数据的接口方法   
  • drag指令访问组件的接口方法获取数据   
  • drop指令访问组件的接口方法传递数据
我们将全局自界说指令的相关代码封装到一个es6的class里面,并作为一个单独的js文件放到项目里,大概发布到npm上,然后在main.js里导入这个类,调用静态初始化方法,即可完玉成局指令的注册。如许一来,项目当中的恣意组件都可以利用v-drag和v-drop了,上面总结的五个步骤,只必要实现第2、3条即可。
以上就是如何利用vue自界说指令构建拖放插件的具体内容,更多关于vue自界说指令构建拖放插件的资料请关注草根技术分享其它相关文章!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作