• vue下使用drag完成简单拖拽


    因为没有时间研究jquery的sortable功能(也没有文档),所以用HTML5的drag完成了简单的拖拽,这里记录下

    `@dragstart` , `@dragover` , `@dragend` , `dragable`

    dragable 确认可以被拖拽的元素

    <ul @dragstart="onDragStart($event)" 
       @dragover="onDragOver($event)" @dragend="onDragEnd($event)" ref="box"> <li v-for="(item,index) in options" :index="index" class="item" draggable="true" :value="item.value" :key="item.value" v-show="item._checked"> {{item.label}} </li>
    </ul>

    script内部代码

    /**
           * 拖拽开始
           */
          onDragStart(e) {
            boxHeight = Math.floor(e.target.offsetHeight/2)
            this.draging = e.target
          },
    
    /**
           * 拖拽过程
           */
          onDragOver(e) {
    //      console.log('move', e)
            this.target = e.target
            let targetTop = e.target.getBoundingClientRect().top
            let dragingTop = this.draging.getBoundingClientRect().top
    //      console.log('drag move', targetTop)
            if(this.target.nodeName==='LI'&&this.target !== this.draging) {
              if(this.target&&this.target.animated) {
                return
              }
              let targetIndex = this.target.getAttribute('index')
              let dragingIndex = this.draging.getAttribute('index')
              if(targetIndex > dragingIndex) {//拖拽元素往下移动
                //target的下一个元素
                this.target.parentNode.insertBefore(this.draging, this.target.nextSibling)
              }else{
                this.target.parentNode.insertBefore(this.draging, this.target)
              }
              this._animation(targetTop, this.target)
              this._animation(dragingTop, this.draging)         
            }
          }, 
    
    /**
           * 拖拽结束
           */
          onDragEnd(e) {
            var tOptions = JSON.parse(JSON.stringify(this.options));
            let currentArray = Array.from(this.$refs['box'].childNodes)
            let data = currentArray.map((item,i)=>{
              let obj = tOptions.find(c=>c.value===item.getAttribute('value'))
              obj.index = i
              return obj
            })
            this.options = data
            this.initOptions()        
          },
    
    /**
           * 拖拽的动画过程
           */
          _animation(clientTop, dom) {
            let offset = clientTop - dom.getBoundingClientRect().top //元素移动后的新位置
            //console.log('target+draging', offset)
            dom.style.transition = 'none';
            dom.style.transform = `translateY(${offset}px)`
            //触发重绘
            //console.log('offsetWidth:', dom.offsetWidth)
            //offsetWidth导致了浏览器重绘(了解浏览器重排、重绘)
            dom.style.transition = 'transform 0.3s';
            dom.style.transform = '';
            
            clearTimeout(dom.animated);
            dom.animated = setTimeout(()=>{
              dom.style.transition = ''
              dom.style.transform = ''
              dom.animated=false
            },150)        
          },
              

    这样简单的拖拽就完成了,在这里要着重强调 `v-for` 的情况下,key值很重要,因为key值我给的是index值,发现每次排完序之后都是没重新排序的样子,犯了低级错误

    key 为每个节点提供身份标识,数据改变时会重排,所以最好绑定唯一标识。

    注意:如果用index标识可能得不到想要的效果,所以我在项目中使用了每个元素的value来作为 key

  • 相关阅读:
    【学习总结】 小白CS成长之路
    Java程序员面试题收集(1)
    ECSTORE2.0 去页面底部版权
    vue-cli安装
    linux下安装nodejs
    Access denied for user 'root'@'localhost' (using password: YES)的解决
    想说的话
    十三:CSS之CSS的四种使用方法和优先级
    十二:CSS之基础语法
    十一:HTML之实现基本网页结构
  • 原文地址:https://www.cnblogs.com/feijiediyimei/p/13397514.html
Copyright © 2020-2023  润新知