this.$set(this.linkArr[index],'name',“小王”);
這是這次系列文章的第一篇,我自己封裝了一個用vue實現的拖動卡片組件,並且發布到npm,詳細地記錄下來了整體制作過程。總共有三篇文章,介紹組件的制作思路和遇到的問題,以及在發布到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
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。