vue卡片拖拽、自動排列交換位置、拖拽數據存取


this.$set(this.linkArr[index],'name',“小王”);

 

這是這次系列文章的第一篇,我自己封裝了一個用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
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM