Vue中实现元素拖动效果的方法介绍

19 篇文章 3 订阅

一、H5原生的drag&drop

  • draggable=true(必需)
  • ondragstart:拖动开始时触发
  • ondrag:拖动过程中触发
  • ondragend:拖动结束触发
  • ondragenter :被拖动元素进入到目标区域时触发
  • ondragover :被拖动元素在目标区域移动时触发
  • ondragleave :被拖动元素离开目标区域时触发
  • ondrop :释放鼠标时触发

二、实际例子

2.1 被拖动元素–折叠面板(子组件)

<template>
  <div>
      <a-collapse @change="handleCollapseChange($event, step, index)" draggable="true" @dragstart.native="dragStart($event, step, index)">
        <a-collapse-panel key="1" :forceRender="true">
          <span slot="header">
            <!--编辑页面使用-->
            <span v-if="(step.sceneStepType === 'HTTP用例') || (step.sceneStepType === 'RPC用例') || (step.sceneStepType === '场景用例')">Step{{index + 1}}   {{step.sceneStepName}}</span>
            <span v-if="step.sceneStepType === 'GET请求'">Step{{index + 1}}
              <a-input style="width: 20%" v-model="step.sceneStepName" @click="handleGetRequestChange($event, step)"></a-input>
            </span>
            <span v-if="step.sceneStepType === '条件' && !step.hasOwnProperty('sceneCaseStepResult')">Step{{index + 1}}  If
            <a-input style="width: 10%" v-model="step.sceneFirstExpression" @click="handleFirstExpressionChange($event, step)"></a-input>
            <a-select style="width: 10%" v-decorator="['sceneExpressionJudgeCondition',{ initialValue: step.sceneExpressionJudgeCondition, rules: [{message: 'Please select your gender!' }] },]" placeholder="Select a option and change input text above" @change="handleSelectChange($event, step)">
              <a-select-option v-for="item in stepResultVerifyList" :value="item" :key="item">
                {{item}}
              </a-select-option>
            </a-select>
            <a-input style="width: 10%" v-model="step.sceneSecondExpression" @click="handleSecondExpressionChange($event, step)"></a-input>
          </span>
            <span style="float: right;"><a-icon type="delete" @click="deleteSceneCaseStepById"/></span>
            <!--历史记录查看详情使用-->
            <span v-if="step.hasOwnProperty('interfaceType')">
            <span>Step{{index + 1}}   {{step.testpoint}}  <span style="float: right">运行结果:<a-icon v-if="step.result === 'T'" type="check" style="color: green"/><a-icon v-else type="close" style="color: red"/></span></span>
          </span>
            <span v-if="step.sceneStepType === '条件' && step.hasOwnProperty('sceneCaseStepResult')">Step{{index + 1}}  If
            <a-input style="width: 10%" v-model="step.sceneFirstExpression" @click="handleFirstExpressionChange($event, step)"></a-input>
            <a-select style="width: 10%" v-decorator="['sceneExpressionJudgeCondition',{ initialValue: step.sceneExpressionJudgeCondition, rules: [{message: 'Please select your gender!' }] },]" placeholder="Select a option and change input text above" @change="handleSelectChange($event, step)">
              <a-select-option v-for="item in stepResultVerifyList" :value="item" :key="item">
                {{item}}
              </a-select-option>
            </a-select>
            <a-input style="width: 10%" v-model="step.sceneSecondExpression" @click="handleSecondExpressionChange($event, step)"></a-input>
            <span>(1 = 01)</span>
            <span style="float: right">判断结果:<a-icon v-if="step.sceneCaseStepResult === 'T'" type="check" style="color: green"/><a-icon v-else type="close" style="color: red"/></span>
          </span>
            <span v-if="step.sceneStepType === '等待'">Step{{index + 1}} 等待 <a-input style="width: 10%" v-model="step.sceneStepWaitingtime" @click="handleWaitTimeChange($event, step)"></a-input> 毫秒</span>
          </span>
          <!--折叠面板内容-->
          <!--编辑页面使用-->
          <div v-if="step.sceneStepType === 'GET请求' && !step.hasOwnProperty('sceneCaseStepResult')">
            <a-input v-model="step.sceneStepGetUrl" @click="handleGetUrlChange($event, step)"></a-input>
            <br/>
            <scene-case-step-get-request ref="sceneCaseStepGetRequestObj" @fromSceneCaseStepGetRequest="fromSceneCaseStepGetRequest(step, $event)"/>
          </div>
          <!--历史记录查看详情使用-->
          <div v-if="step.hasOwnProperty('interfaceType')">
            <interface-case-debug-common-details ref="interfaceCaseDebugCommonDetailsObj" :caseTotalData="step"/>
          </div>
          <div v-if="step.sceneStepType === 'GET请求' && step.hasOwnProperty('sceneCaseStepResult')">
            <interface-case-debug-common-details ref="interfaceCaseDebugCommonDetailsObj" :caseTotalData="step"/>
          </div>
        </a-collapse-panel>
      </a-collapse>
  </div>
</template>

拖动开始时触发的方法如下,主要作用是向父组件传递了正在拖动的元素的数据信息

dragStart (e, step, index) {
  console.log('dragStart e', e)
  // e.dataTransfer.setData('my-info', 'hello')
  // e.dataTransfer.setData('my-extra-info', 'world')
  this.$emit('fromSceneCaseCommonStepsPage', step)
 },

2.2 父组件

@dragover.prevent 必须加

<div style="margin: 8px">
   <a-timeline>
       <a-timeline-item v-for="(step, index) in steps" :key="index" @drop="drop($event, step)" @dragover.prevent>
          <scene-case-common-steps-page :step="step" :index="index" @fromSceneCaseCommonStepsPage="fromSceneCaseCommonStepsPage"/>
       </a-timeline-item>
   </a-timeline>
</div>

子组件将数据传递给了父组件中的对象

    fromSceneCaseCommonStepsPage (data) {
      this.dragging = data
    },

drop释放鼠标时触发,该方法主要实现了元素位置互换的功能

   drop (e, step) {
      console.log('drop', e)
      // console.log(e.dataTransfer.getData('my-info'))
      // console.log(e.dataTransfer.getData('my-extra-info'))
      e.dataTransfer.dropEffect = 'move'

      if (step === this.dragging) {
        return
      }
      const newItems = [...this.steps]
      const from = newItems.indexOf(this.dragging)
      const to = newItems.indexOf(step)
      newItems[from] = step
      newItems[to] = this.dragging
      this.steps = newItems
    },
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值