Let’s first demonstrate the final result:

Smoothly drag and swap location effects, and update data in real time

Support component style and content customization

In the first article in this series, I packaged a drag and drop card component in VUE and posted it to NPM, documenting the whole process in detail. In total, there are three articles that describe how the component was made and the problems encountered, as well as what happened and how to solve the problems when it was published to NPM and downloaded for use.

  • The first part is the usage document and introduction after component encapsulation
  • The second part is the implementation of components and details
  • Part 3: How to package and upload components to NPM, load on demand and use them after download.

This is the drag card component implemented by VUE, which mainly implements:

  • The position of drag card is changed with that of other cards, and other cards are automatically moved according to the position of drag, and the position data is updated in real time
  • You can use the mouse to scroll while dragging
  • The card is generated based on the data, and all parameters and contents can be customized for different scenarios
  • Events of different operations can be obtained, and the location data will be updated in real time after dragging
  • It can be installed globally and loaded on demand

How to use it?

Download carddragger

npm install carddragger
Copy the code

Current stable version: 0.3.6, updated 10/24/11 am

Global installation

Use it in the entry js file of your vue project. Vue-cli generated projects are usually main.js files

import {installCardDragger} from 'carddragger'
Vue.use(installCardDragger)
Copy the code

According to the need to load

Import directly from components

import { cardDragger } from 'carddragger'

export default {
  components:{
    cardDragger,
  }
}
Copy the code

Use the sample

1. Basic use:

<template>
  <cardDragger :data="cardList">
  </cardDragger>
</template>
<script>
export default {
  data() {
    return {
      cardList: [{
        positionNum: i,
        name: "Presentation card"+i,
        id: "card"+i,
      }],
    }
  }
}
</script>
Copy the code

2. Complete example: Clone the entire project by referring to the examples in the source repository, NPM install+ NPM run serve can see the complete example

Props (parameters)

attribute instructions type The default value
data This parameter is mandatory. The card data to be passed in is required Array
colNum The number of columns in which the card is arranged Number 2
cardOutsideWidth The width of the outside of the card to be occupied (including the content-free part) Number 590
cardOutsideHeight The height of the outside of the card (including the part without content) Number 380
cardInsideWidth Card width Number 560
cardInsideHeight Card height Number 320

Example data format:

The content of the card is generated or customized based on the 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: "Test Card 2",
                    id: "card2",
                }
            ]
        }
    }
}
</script>
Copy the code
attribute instructions type The default value
id This parameter is mandatory. Set the id of the card as a unique identifier String
positionNum Mandatory. Sets the card position, increasing from 1 Number
name Optional, set the card title name String ‘Default title’
componentData This parameter sets the card content to component data. If this parameter has data, the data passed into slot is invalid component

Slot (s)

First of all, the card is divided into two parts:

  • The upper part is divided into the title bar of the card, and the drag event is triggered only when the upper part is clicked
  • The lower part is divided into the contents of the card

Both sections are customizable in content and style. If no custom content is added, the title bar and content have a white background by default, showing the name in data. If you add custom content, you need to set the background.

Title bar slot

<cardDragger :data="cardList"> <! Insert template in the middle of the component and set V-slot :header="slotProps"Header is the name of the slot in the title bar, and the content in it will render to the slotProps of each of your card title bars is the data returned from the child components, and the data of each object in the data array --> <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 > Default title </div> </div> </template> </cardDragger>Copy the code

The content of the slot

<cardDragger :data="cardList"> <! -- Same as title bar slot, but note that v-slot:content--> <template v-slot:content="slotProps">
    <div class="insideData">
      {{slotProps.item.name}}
    </div>
  </template>
</cardDragger>
Copy the code

You can also

<cardDragger :data="cardList"> <! -- Same as title bar slot, but note that v-slot:content--> <template v-slot:content="slotProps">
     <component :is="slotProps.item.OtherData"></component> <! </template> </cardDragger> // omit some code and load your component import exampleChild1 from"./childComponent/exampleChild1"

cardList: [
    {
      positionNum: 1,
      name: "Presentation Card 1",
      id: "card1"OtherData:exampleChild1 //OtherData :exampleChild1 //OtherData :exampleChild1Copy the code

I made another judgment about the content, you can put the required components in data’s componentData property, the content will automatically read componentData data. Of course, you can ignore this property by simply using slot.

import exampleChild1 from "./childComponent/exampleChild1"CardList: [{positionNum: 1, name:"Presentation Card 1",
      id: "card1"ComponentData: exampleChild1, / / setting can be used directly Custom attributes: {itemData:{Props = Props () {itemData:{componnetData :{Props = Props () {itemData:{componnetData :{Props = Props () {itemData:{componnetData :{type:Object
    }
}
Copy the code

Render priority: Data’s componentData > Slot > default content

The Events of the day

startDrag

Trigger this function when the title bar at the top of the card is clicked

Parameters: startDrag (event, id)

The first parameter, event, is the native event of the click event and the second parameter, ID, is the ID of the selected card

swicthPosition

Function: Raises this event when a card is dragged to another card’s location

Parameters: swicthPosition (oldPositon newPositon, originItem)

The first parameter oldPositon is the original position number of the card. The second parameter newPositon is the position number of the card to be exchanged. The third parameter originItem is the data after the card exchange is completed

finishDrag

Action: This event is triggered when the mouse is released after the drag is complete

Parameters: swicthPosition (oldPositon newPositon, originItem)

The first parameter oldPositon is the original position number of the card. The second parameter newPositon is the position number of the card to be exchanged. The third parameter originItem is the data after the card exchange is completed

Consider fixes

1. If the positionNum of data is empty, an error will be reported. The positionNum must be incremented from 1. But it seems that this scenario is not often used, consider fixing ING.

Future plans

  • I’ll package a React version if necessary
  • Modify other required parameters and extend

If you think this series is interesting, please give it a thumbs up.