vue卡片拖拽、自动排列交换位置、拖拽数据存取

这是这次系列文章的第一篇,我自己封装了一个用vue实现的拖动卡片组件,并且发布到npm,详细地记录下来了整体制作过程。总共有三篇文章,介绍组件的制作思路和遇到的问题,以及在发布到npm上并下载使用的过程中,发生了什么问题并如何解决。

这是vue实现的拖动卡片组件,主要实现了

  • 拖动卡片与其他卡片的位置更换,并且其他卡片根据拖动的位置自动顺移,位置数据实时更新
  • 拖动的时候可使用鼠标滚动
  • 卡片根据数据生成,所有参数和内容都是可以自定义的,方便应用于不同场景
  • 不同操作的事件都可获取到,拖动后的位置数据会实时更新
  • 可以全局安装和按需加载

如何使用?

下载carddragger

npm install carddragger

全局安装

在你vue项目的入口js文件中使用,vue-cli生成的项目一般为main.js文件

import {installCardDragger} from ‘carddragger‘
Vue.use(installCardDragger)

按需加载

在组件中直接import

import { cardDragger } from ‘carddragger‘

export default {
  components:{
    cardDragger,
  }
}

使用示例

1.基础使用:

<template>
  <cardDragger :data="cardList">
  </cardDragger>
</template>
<script>
export default {
  data() {
    return {
      cardList: [{
        positionNum: i,
        name: "演示卡片"+i,
        id: "card"+i,
      }],
    }
  }
}
</script>

2.完整示例:
参照源码仓库中的examples
将整个项目clone下来,npm install+npm run serve即可看到完整示例

Props(参数)

属性 说明 类型 默认值
data 必填,需要传入的卡片数据,具体格式请看下方解释 Array -
colNum 卡片排列的列数 Number 2
cardOutsideWidth 卡片外部需要占据的宽度(包括无内容部分) Number 590
cardOutsideHeight 卡片外部需要占据的高度(包括无内容部分) Number 380
cardInsideWidth 卡片的宽度 Number 560
cardInsideHeight 卡片的高度 Number 320
detectDistance 卡片拖动的时候,会触发交换位置的最小距离 Number 50

data格式示例:

卡片的内容根据data数据生成或自定义

<template>
    <div>
        <cardDragger
        :data="cardList"
        :colNum="4"
        :cardOutsideWidth="300"
        :cardInsideWidth="260"
        :cardOutsideHeight="310"
        :cardInsideHeight="240"
        />
        <!-- 上面的属性都可自定义 -->
    </div>
</template>

<script>
export default {
    data(){
        return{
            cardList: [
                {
                    positionNum: 2,
                    name: "测试卡片2",
                    id: "card2",
                }
            ]
        }
    }
}
</script>
属性 说明 类型 默认值
id 必填,设置卡片的id作为唯一识别 String -
positionNum 必填,设置卡片位置,从1开始依次递增 Number -
name 选填,设置卡片的标题名称 String ‘默认标题‘
componentData 选填,设置卡片的内容为组件数据,如果此参数具有数据的话,则slot传入的数据失效 Array -

Slot(插槽)

首先先介绍一下,卡片内容分为上下两部分:

  • 上部分为卡片的标题栏,并且拖拽事件只有点击上部分才触发
  • 下部分为卡片的内容

两个部分都是可以进行自定义内容及样式的。若不添加的自定义内容的话,标题栏和内容都是默认背景为白色,显示data中的name。若添加了自定义内容则背景需要自己设置。

标题栏插槽

<cardDragger :data="cardList" >
  <!-- 在组件中间插入template并设置 v-slot:header="slotProps"
       header为标题栏的插槽名字,在里面的内容会渲染到你每一个卡片标题栏上
       slotProps为从子组件返回的数据,及data数组里面的每一个对象数据-->
  <template v-slot:header="slotProps">
    <!-- 自定义内容 -->
    <div class="topMenuBox" >
      <div class="menuTitle" v-if="slotProps.item.name">{{slotProps.item.name}}</div>
      <div class="menuTitle" v-else> 默认标题 </div>
    </div>
  </template>
</cardDragger>

内容插槽

<cardDragger :data="cardList">
  <!-- 与标题栏插槽一致,但需要注意v-slot:content-->
  <template v-slot:content="slotProps">
    <div class="insideData">
      {{slotProps.item.name}}
    </div>
  </template>
</cardDragger>

你也可以

<cardDragger :data="cardList">
  <!-- 与标题栏插槽一致,但需要注意v-slot:content-->
  <template v-slot:content="slotProps">
     <component :is="slotProps.item.OtherData"></component>
     <!--这里用到的是vue的动态组件功能动态渲染组件,可传入更多属性至子组件 -->
  </template>
</cardDragger>

//省略部分代码,加载你的组件
import exampleChild1 from "./childComponent/exampleChild1"

cardList: [
    {
      positionNum: 1,
      name: "演示卡片1",
      id: "card1",
      OtherData:exampleChild1
      //OtherData这个是你自己定义的属性,注意不可与componentData属性名字重复
    }
]

关于内容我做了另外一个判断,你可以将需要的组件放在data的componentData属性里面,内容会自动读取componentData的数据。当然你直接都使用slot就可以忽略这个属性。

import exampleChild1 from "./childComponent/exampleChild1"
//省略部分代码
cardList: [
    {
      positionNum: 1,
      name: "演示卡片1",
      id: "card1",
      componentData:exampleChild1   //直接设置即可使用 

      /*componnetData传入的组件,可传入两个我定义好的Props
      animationState:{
        类型:Boolean,
        功能:首次加载卡片的时候为true,之后为false
      }
      itemData:{
        类型:Object,
        功能:传入组件数据
      }
      */
    }
]

//在子组件中使用props即可使用
props:{
    animationState:{
      type:Boolean,
      default:true
    },
    itemData:{
      type:Object
    }
}

渲染优先级:data的componentData > slot > 默认内容

Events(事件)

startDrag

事件作用
在点击卡片顶部标题栏的时候,触发此函数

事件参数
startDrag(event,id)

第一个参数event,是点击事件的原生event
第二个参数id,是选中的卡片的id

swicthPosition

作用
在拖动一个卡片到另外一个卡片的位置的时候,触发此事件

事件参数
swicthPosition(oldPositon,newPositon,originItem)

第一个参数oldPositon,是卡片原来的位置号码
第二个参数newPositon,是卡片需要交换的位置号码
第三个参数originItem,是卡片交换完成后的数据

finishDrag

事件作用
拖拽完成松开鼠标后,触发此事件

事件参数
swicthPosition(oldPositon,newPositon,originItem)

第一个参数oldPositon,是卡片原来的位置号码
第二个参数newPositon,是卡片需要交换的位置号码
第三个参数originItem,是卡片交换完成后的数据

作者:裂泉
链接:https://juejin.im/post/5da53e29e51d457822796ed8
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/xiaolucky/p/11699715.html

时间: 2024-10-29 17:52:26

vue卡片拖拽、自动排列交换位置、拖拽数据存取的相关文章

照片墙效果(交换位置还未实现)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <st

listview长按后拖动item交换位置的帮助类

抽象类封装,需要在activity中创建帮助类对象并重写交换位置的方法changeItemPosition(数据源中id1,数据源中的id2),和重新显示listview的方法resetListview 关键步骤: 1.listview正常显示后,新建lmxListviewHelper对象并传入listview对象,重写两个抽象方法 2.打开item交换功能--> helper.enableChangeItems(true); 效果,长按某一item后,该条目会变成半透明,此时拖动该item移动

c# winform panel 流式布局 panel块可自动排列

代码下载地址  http://download.csdn.net/detail/simadi/7677053 c# winform panel 流式布局 panel块可自动排列,布布扣,bubuko.com

原生js实现三个div层动态交换位置

html代码部分 <!--触发变换按钮--> <input type="button" onclick="startMove()" value="点击"/> <!--主体部分--> <div class="localbox"> <div id="b1" class="block1"></div> <div id

Android游戏开发中如何将两个图标交换位置

Android 游戏界面中有时候因为布局的美观,需要将两个图标交换位置.这两个图标不是简单地更改id号就可以的,下面是交换两个图标的方法. 原代码中相关程序: 未修改前: float pic_x=200;float pic_y=130; 需要修改的第一部分程序,这一部分利用定义pic_x,pic_y的将图标绘制在相应的界面位置中. 第一个图标位置绘图 if(backmusicFlag01)        {                      canvas.drawBitmap(backM

js 实现数组元素交换位置

/** * 数组元素交换位置 * @param {array} arr 数组 * @param {number} index1 添加项目的位置 * @param {number} index2 删除项目的位置 * index1和index2分别是两个数组的索引值,即是两个要交换元素位置的索引值,如1,5就是数组中下标为1和5的两个元素交换位置 */function swapArray(arr, index1, index2) {   arr[index1] = arr.splice(index2

134在单元格中自动排列指定的数据

效果如下: ViewController.h 1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UITableViewController 4 @property (strong, nonatomic) NSMutableArray *mArrDataList; 5 @property (strong, nonatomic) NSMutableArray *mArrSortedCollation; 6 7 @end ViewCo

用C语言把双向链表中的两个结点交换位置,考虑各种边界问题。

用C语言把双向链表中的两个结点交换位置,考虑各种边界问题. [参考] http://blog.csdn.net/silangquan/article/details/18051675

java数组交换位置,定义临时变量后,交换公式顺序问题

public class array01 { public static void main(String[] args){ int[] array = {32,4,56,34,17,39,68,25};//定义一个无序数组 for(int i=0;i<array.length-1;i++){ for(int j=0;j<array.length-i-1;j++){ if(array[j]>array[j+1]){ int temp = array[j];//定义一个临时变量用于交换位置