最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3使用拖拽組件draggable.next的保姆級(jí)教程

 更新時(shí)間:2023年06月06日 11:23:45   作者:糯米飯團(tuán)飯米糯  
做項(xiàng)目的時(shí)候遇到了一個(gè)需求,拖拽按鈕到指定位置,添加一個(gè)輸入框,這篇文章主要給大家介紹了關(guān)于vue3使用拖拽組件draggable.next的保姆級(jí)教程,需要的朋友可以參考下

環(huán)境:vue3+setup語(yǔ)法

首先放官方文檔的鏈接:

中文版本: https://www.itxst.com/vue-draggable-next/tutorial.html (民間翻譯)

英文版本:https://github.com/SortableJS/vue.draggable.next

因?yàn)樽约簩?xiě)的過(guò)程中,官方文檔和網(wǎng)上的資料都非常不明,使用版本各不相同,極易踩坑,自己寫(xiě)完后就總結(jié)一下,與諸位共勉。

(一)首先,明確需求:

做一個(gè)可重復(fù)拖拽生成的表格設(shè)計(jì)器,效果圖如下:

(二)搭一個(gè)基本的可互相拖拽的框架

(1)在終端使用npm命令下載插件

npm i -S vuedraggable@next
//導(dǎo)入
import draggable from 'vuedraggable'

(2)拖拽插件大致可分為兩種使用方式——分組拖拽與單組拖拽

單組拖拽為只有一組數(shù)據(jù),而拖拽是交換此組數(shù)據(jù)內(nèi)部的位置,如下圖所示:

而互相拖拽是有兩組數(shù)據(jù),兩組數(shù)據(jù)可以各自?xún)?nèi)部換順序,可以相互拖拽到對(duì)方的數(shù)組中。

本文需求只用到了互相拖拽,互相拖拽的代碼形式如下:

    //需要克隆的數(shù)據(jù),A組
    <draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }"
      :sort="false" itemKey="id">
      <template #item="{ element }">
        <div class="item move">
          <label class="move">{{ element.name }}</label>
        </div>
      </template>
    </draggable>
//拖拽的結(jié)果,B組
 <draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list" :fallback-class="true"
    :fallback-on-body="true">
    <template #item="{ element }">
      <div class="item move">
        <label class="move">{{ element.name }}</label>
      </div>
    </template>
  </draggable>
<script lang="ts" setup>
import draggable from 'vuedraggable'
interface type {
  name: string,
  id: number
}
const dragList: type[] = reactive<type[]>([
  { name: "單行文本", id: 1 },
  { name: "多行文本", id: 2 },
  { name: "計(jì)數(shù)器", id: 3 },
  { name: "單選框組", id: 4 },
])
const widgetList = reactive<type[]>([
  { name: "多行文本", id: 2 },
])

draggable的一些常用的屬性我作了整理,方便根據(jù)不同的需求取用,可核對(duì)表格填寫(xiě):

屬性
說(shuō)明
類(lèi)型
是否必填

group

如果是分組拖拽,可通過(guò)設(shè)置group的name來(lái)實(shí)現(xiàn)分類(lèi)。

pull屬性代表拖出,put為拖入,

:group="{ name :'list',pull : true, put: false }"

代表這個(gè)分組與其他name為list的分組可實(shí)現(xiàn)分組拖拽,此分組允許拖出,不允許拖入,pull為‘clone’則代表clone模式,pull與put可寫(xiě)可不寫(xiě),默認(rèn)值都為true

Object / string

(分組拖拽時(shí)必填)

list

綁定的數(shù)據(jù)

Array

sort

是否開(kāi)啟排序功能,默認(rèn)為true,如果設(shè)置為false,它所在組無(wú)法排序

Boolean

force-fallback

默認(rèn)false,忽略HTML5的拖拽行為,因?yàn)閔5里有個(gè)屬性也是可以拖動(dòng),你要自定義ghostClass chosenClass dragClass樣式時(shí),建議forceFallback設(shè)置為true

Boolean

(設(shè)置ghost-class或drag-class時(shí)為必填)

ghost-class

:ghostClass=“ghostClass” 設(shè)置拖動(dòng)元素的占位符類(lèi)名,可以將拖動(dòng)時(shí)的元素設(shè)置為不同的樣式。自定義樣式可能需要加!important才能生效,并把forceFallback屬性設(shè)置成true。

String

disabled

是否禁用,默認(rèn)false

Boolean

drag-class

:drag-class="dragClass"拖動(dòng)元素的樣式,你的自定義樣式可能需要加!important才能生效,并把forceFallback屬性設(shè)置成true

Boolean

item-key

每個(gè)元素唯一的標(biāo)識(shí),建議使用id

itemKey='id',注意,此處無(wú)需寫(xiě)成變量形式

String

(不填也能運(yùn)行,但控制臺(tái)會(huì)報(bào)警告)

到現(xiàn)在為止,這已經(jīng)是個(gè)互相拖拽的組件了。

(3)如果發(fā)現(xiàn)自己寫(xiě)的組件 不能進(jìn)行拖拽,或者網(wǎng)頁(yè)上不顯示組件 ,或者出現(xiàn)紅色報(bào)錯(cuò)信息,則檢查以下注意點(diǎn) :

  1. group中name是否一致,group為變量,需要 :group =‘{name:'' }’的形式
  2. AB組的元素要實(shí)現(xiàn)互相拖拽,元素的數(shù)據(jù)結(jié)構(gòu)必須完全一致,如果不放心,可以使用interface來(lái)定義一個(gè)類(lèi)型諸如 interface itemType { name : string , id:number }
  3. AB組綁定的數(shù)組是否為響應(yīng)式,如非響應(yīng)式,會(huì)發(fā)生拖拽成功,但不能及時(shí)響應(yīng)的情況,可以用這個(gè)方法自檢-->先進(jìn)行拖拽,然后在代碼的html部分隨便加個(gè)東西,然后保存,觀(guān)察網(wǎng)頁(yè)上是否顯示剛才拖拽的內(nèi)容,如果出現(xiàn),那就是數(shù)組非響應(yīng)式的問(wèn)題。
    改正:const arr = reactive<itemType[]>([ { name : 'name ' , id : 1 } ])
  4. 在新版vue3中,item插槽是必寫(xiě)的部分,不能使用v-for循環(huán)替代。
<draggable>
    <template #item="{ element }">
        <div class="item move">
          <label class="move">{{ element.name }}</label>
        </div>
      </template>
</draggable>

5.item插槽中只允許有一個(gè)子元素,此處有個(gè)坑,就是如果有兩個(gè)子元素,但注釋掉了一個(gè),也會(huì)報(bào)錯(cuò)。哪怕實(shí)際上這只有一個(gè)子元素。

//正確的  
<template #item="{ element }">
      <div class="item move">
        <label class="move">{{ element.name }}</label>
      </div>
 </template>
//會(huì)報(bào)錯(cuò)的情況!
<template #item="{ element }">
      <!-- <div class="class"></div> -->
      <div class="item move">
        <label class="move">{{ element.name }}</label>
      </div>
 </template>

到此為止,已經(jīng)實(shí)現(xiàn)拖拽成功。有些人可能會(huì)碰到這個(gè)問(wèn)題————如果B組為空,向B組內(nèi)拖第一個(gè)組件的時(shí)候,會(huì)出現(xiàn)拖拽困難,只能往拖拽區(qū)的最頂部拖才能成功 / 根本無(wú)法拖拽成功。

原因:因?yàn)锽組的draggable渲染時(shí)為一個(gè)高度為auto的div,當(dāng)前組如果為空,高度也為0,可拖拽區(qū)就會(huì)變得很小或不存在。

解決方法:為B組的draggable設(shè)計(jì)高度,具體代碼為添加類(lèi)名,在css中設(shè)置

<draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list" :fallback-class="true"
    :fallback-on-body="true" class="drag-content">
    <template #item="{ element }">
      <div class="item move">
        <label class="move">{{ element.name }}</label>
      </div>
    </template>
  </draggable>
<style lang="less" scoped>
    .drag-content {
        height:500px; //建議是外層嵌套一層div,div固定高,此處再設(shè)為100%
    }
</style>

(三)將拖拽后的內(nèi)容替換為element組件/其它指定內(nèi)容

我們發(fā)現(xiàn),拖拽后顯示的內(nèi)容可自由定義,在B組的draggable中設(shè)置

此時(shí),我們需要完善dragList的數(shù)組結(jié)構(gòu),來(lái)映射拖拽后所形成的不同組件

(在組件少的情況下可以這么做)

interface itemType {
  name: string,
  id: number,
  element:string
}
 
const dragList: type[] = reactive<type[]>([
  { name: "單行文本", id: 1, element: 'Input' },
  { name: "多行文本", id: 2, element: 'Textarea' },
  { name: "計(jì)數(shù)器", id: 3, element: 'InputNumber' },
  { name: "單選框組", id: 4, element: 'Radio' },
])
 
const widgetList = reactive<type[]>([
 
])
//  A組
<draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }"
      :sort="false" itemKey="id">
      <template #item="{ element }">
        <div class="item move">
          <label class="move">{{ element.name }}</label>
        </div>
      </template>
    </draggable>
// B組
    <draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list"
      :fallback-class="true" :fallback-on-body="true" class="drag-content">
      <template #item="{ element }">
        <div class="item move">
          <label class="move title">{{ element.name }}</label>
          <div> <el-input v-model="input" placeholder="Please input" v-if="element.element === 'input'" /></div>
          <div><el-input v-model="textarea" :rows="2" type="textarea" placeholder="Please input"
              v-if="element.element === 'textarea'" /> </div>
        </div>
      </template>
    </draggable>

點(diǎn)擊控件拖過(guò)去,就可以實(shí)現(xiàn)如下的效果,如果不想要標(biāo)題,可以把label部分去掉,其他控件如法炮制即可:

在組件數(shù)量少的時(shí)候,可以這么做,但數(shù)量多時(shí),建議使用component標(biāo)簽來(lái)映射

(1)先更改一下文件的結(jié)構(gòu)

(2)寫(xiě)一個(gè)公共的函數(shù)去返回當(dāng)前widgets文件夾下的所有文件

// getWidget.ts
 
const gets = {} as any 
const modules = import.meta.glob('./*.vue', {eager:true})
for (let each in modules) {
  const name = (modules[each] as any).default.__name
  gets[name] = (modules[each] as any).default
}
 
console.log(gets);
 
export default gets

也可使用globEager方法,編譯器會(huì)報(bào)錯(cuò):函數(shù)已經(jīng)棄用,不過(guò)不影響使用。

(3)分別把每個(gè)組件的部分寫(xiě)好

// Input.vue
<template>
  <div>
    <el-input v-model="input" placeholder="Please input"  />
  </div>
</template>
  
<script lang="ts" setup>
 
 const input=ref('')
</script>
 
<style lang="less" scoped>
 
</style>

(四)使用component標(biāo)簽映射

 
    <draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list"
      :fallback-class="true" :fallback-on-body="true" class="drag-content">
      <template #item="{ element }">
 
        <div class="item move">
          <label class="move title">{{ element.name }}</label>
          <div>
            <component :is="getWidget(element.element)"></component>
          </div>
        </div>
      </template>
    </draggable>
  
 
// 使用函數(shù)映射
 
<script lang="ts" setup>
import draggable from 'vuedraggable'
//要注意導(dǎo)入
import getName from './widgets/getWidget'
 
const getWidget = (name: string) => {
//寫(xiě)的時(shí)候,組件的起名一定要與dragList中的element名字一模一樣,不然會(huì)映射不上
  return getName[name]
}

(五)最終效果

成功實(shí)現(xiàn)!

總結(jié) 

到此這篇關(guān)于vue3使用拖拽組件draggable.next的保姆級(jí)教程的文章就介紹到這了,更多相關(guān)vue3拖拽組件draggable.next內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue3+vite+tdesign實(shí)現(xiàn)日歷式可編輯的排課班表填寫(xiě)功能

    vue3+vite+tdesign實(shí)現(xiàn)日歷式可編輯的排課班表填寫(xiě)功能

    本文介紹了如何使用Vue3和tdesign實(shí)現(xiàn)一個(gè)日歷式、可編輯的排班填寫(xiě)功能,開(kāi)發(fā)過(guò)程中面臨了年份和月份下拉框的實(shí)現(xiàn)、周期顯示以及可編輯日歷的樣式和數(shù)據(jù)獲取等挑戰(zhàn),感興趣的朋友一起看看吧
    2025-01-01
  • Vue中如何對(duì)ElementUI的Dialog組件封裝

    Vue中如何對(duì)ElementUI的Dialog組件封裝

    這篇文章主要介紹了Vue中如何對(duì)ElementUI的Dialog組件封裝問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Vue3中依賴(lài)注入provide、inject的使用

    Vue3中依賴(lài)注入provide、inject的使用

    這篇文章主要介紹了Vue3中依賴(lài)注入provide、inject的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue項(xiàng)目打包后,由于html被緩存導(dǎo)致出現(xiàn)白屏的處理方案

    vue項(xiàng)目打包后,由于html被緩存導(dǎo)致出現(xiàn)白屏的處理方案

    這篇文章主要介紹了vue項(xiàng)目打包后,由于html被緩存導(dǎo)致出現(xiàn)白屏的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • VUE?Element修改el-input和el-select長(zhǎng)度的具體步驟

    VUE?Element修改el-input和el-select長(zhǎng)度的具體步驟

    這篇文章主要給大家介紹了關(guān)于VUE?Element修改el-input和el-select長(zhǎng)度的具體步驟,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-12-12
  • vue腳手架配置預(yù)渲染及prerender-spa-plugin配置方式

    vue腳手架配置預(yù)渲染及prerender-spa-plugin配置方式

    這篇文章主要介紹了vue腳手架配置預(yù)渲染及prerender-spa-plugin配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue Ref全家桶具體用法詳解

    Vue Ref全家桶具體用法詳解

    ref用來(lái)輔助我們獲取DOM元素或組件的引用實(shí)例對(duì)象,每個(gè)vue的組件實(shí)例上,都包含一個(gè)refs對(duì)象,里面存儲(chǔ)著對(duì)應(yīng)的DOM元素或組件的引用,默認(rèn)情況下,組件的refs指向一個(gè)空對(duì)象
    2023-03-03
  • Vue中nextTick的原理分析

    Vue中nextTick的原理分析

    本文詳細(xì)介紹了Vue中nextTick的原理和使用方法,Vue采用異步渲染機(jī)制,通過(guò)nextTick可以確保在DOM更新后執(zhí)行回調(diào),nextTick依賴(lài)微任務(wù)和宏任務(wù),優(yōu)先使用Promise,降級(jí)到MutationObserver/setTimeout,Vue3進(jìn)一步優(yōu)化了nextTick,減少了復(fù)雜度并提升了性能
    2025-02-02
  • Vue Element如何獲取select選擇框選擇的value和label

    Vue Element如何獲取select選擇框選擇的value和label

    文章介紹了兩種使用Vue.js和ElementUI獲取select選擇框值的方法:一種是使用watch監(jiān)聽(tīng)selectedValue的變化,另一種是使用@change事件,兩種方法都能實(shí)現(xiàn)獲取選擇的value和label
    2025-01-01
  • VUE元素的隱藏和顯示(v-show指令)

    VUE元素的隱藏和顯示(v-show指令)

    本篇文章主要介紹了VUE元素的隱藏和顯示(v-show指令),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06

最新評(píng)論

潜江市| 青海省| 垣曲县| 兰溪市| 正阳县| 江永县| 南乐县| 安远县| 稷山县| 久治县| 成都市| 商城县| 河津市| 呼图壁县| 银川市| 乌恰县| 潮安县| 华坪县| 卢氏县| 彩票| 札达县| 上栗县| 北京市| 洪湖市| 土默特右旗| 六安市| 水富县| 饶河县| 德阳市| 巍山| 德化县| 丘北县| 新巴尔虎左旗| 九江县| 大姚县| 上虞市| 洛阳市| 渭南市| 甘孜| 五大连池市| 略阳县|