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

使用vue-draggable-plus實現(xiàn)拖拽排序

 更新時間:2024年01月11日 11:39:01   作者:迪士尼在逃保安  
最近遇到一個需求,在 Vue3 的一個 H5 頁面當(dāng)中點擊拖拽圖標(biāo)上下拖動 tab 子項,然后點擊保存可以保存最新的 tab 項順序,同事說可以用 vue-draggable-plus 這個庫來實現(xiàn)拖拽,所以本文給大家介紹了如何使用vue-draggable-plus實現(xiàn)拖拽排序,需要的朋友可以參考下

最近實習(xí)期間遇到了一個需求:在 Vue3 的一個 H5 頁面當(dāng)中點擊拖拽圖標(biāo)上下拖動 tab 子項,然后點擊保存可以保存最新的 tab 項順序,當(dāng)時王哥和我說可以用 vue-draggable-plus 這個庫來實現(xiàn)拖拽,因為公司的項目組件用的都是 TSX 寫法,是我之前沒接觸過的,所以寫起來比較慢,整個需求整整花了兩天才完成。下面的代碼展示還是使用傳統(tǒng)的 SFC 寫法。

vue-draggable-plus

首先在項目安裝好 vue-draggable-plus

npm install vue-draggable-plus

具體使用可以參考中文文檔:vue-draggable-plus | vue-draggable-plus (gitee.io)

基本布局

vue-draggable-plus 的使用有三種方式,這里我采用的是組件方式引入:

<template>
    ...
<VueDraggable
   ref="el"
   v-model="sortList"
   :disabled="disabled"
   :animation="150"
   ghostClass="ghost"
   class="flex flex-col gap-2 p-4 w-300px h-300px m-auto bg-gray-500/5 rounded"
   @start="onStart"
   @update="onUpdate"
   filter=".undraggable"
   handle=".handle"
 >
   <div
     class="sort-item"
     v-for="item in sortList"
     :key="item.id"
     :class="item.id === 1 ? 'undraggable' : ''"
     :style="item.id === 1 ? 'opacity:0.3' : ''"
   >
     <img
       class="delete"
       src="./assets/ic_delete.svg"
       @click="removeItem(item.id)"
     />
     <span>{{ item.name }}</span>
     <img class="handle" src="./assets/ic_items.svg" />
   </div>
 </VueDraggable>
    ...
</template>
<script setup lang="ts">
import { ref } from "vue";
import { type UseDraggableReturn, VueDraggable } from "vue-draggable-plus";
...
const sortShow = ref(false);
const el = ref<UseDraggableReturn>();
const disabled = ref(false);
...
</script>

其中@start@update 兩個自定義事件分別在拖拽開始和拖拽完成后調(diào)用,可以在這個期間進行一些邏輯操作,像監(jiān)聽數(shù)組的前后變換等。

禁止部分元素拖動

因為當(dāng)時項目還有一些其他的特殊需求:有些默認(rèn)的子項保持不變,不允許拖拽,這邊也可以用 vue-draggable-plus 實現(xiàn),如上述代碼所示:使用 filter=".undraggable" 過濾類名為 undraggable 的元素,只要是帶有這個類名的元素都無法被拖拽。

指定元素觸發(fā)拖拽

當(dāng)時 UI 還有一個需求,只能點擊側(cè)邊的拖拽按鈕才能實現(xiàn)拖動,可以通過 handle 屬性傳遞一個選擇器,來指定拖拽的句柄,這里我指定的是 handle類名,只有點擊攜帶這個類名的拖拽圖標(biāo)才能實現(xiàn)拖拽。

實現(xiàn)需求基本邏輯:

首先定義兩個數(shù)組 sortListconstList,其中 sortList 用來接收后端傳過來的數(shù)據(jù),后面實現(xiàn)排序完的數(shù)據(jù)也是存在這個數(shù)組當(dāng)中,而 constList 則是作為一個參照數(shù)組與 sortList 進行比較實現(xiàn)元素的動態(tài)增添。最后點擊保存的時候可將 sortList 作為參數(shù)請求保存當(dāng)前順序的接口,因為當(dāng)時后端需要通過 sortOrder字段來判斷排序,所以最后在保存的時候給 sortList 的每個子項都按順序添加一個 sortOrder字段再請求接口,完整代碼如下:

完整代碼

<template>
  <van-button type="success" @click="sortClick">排列菜單</van-button>
  <div v-for="item in sortList" :key="item.id">{{ item }}</div>
  <van-action-sheet v-model:show="sortShow" title="排序管理">
    <div class="content">
      <!-- 當(dāng)前排序 -->
      <div class="current-sort">
        <span class="label">當(dāng)前排序</span>
        <VueDraggable
          ref="el"
          v-model="sortList"
          :disabled="disabled"
          :animation="150"
          ghostClass="ghost"
          class="flex flex-col gap-2 p-4 w-300px h-300px m-auto bg-gray-500/5 rounded"
          @start="onStart"
          @update="onUpdate"
          filter=".undraggable"
          handle=".handle"
        >
          <div
            class="sort-item"
            v-for="item in sortList"
            :key="item.id"
            :class="item.id === 1 ? 'undraggable' : ''"
            :style="item.id === 1 ? 'opacity:0.3' : ''"
          >
            <img
              class="delete"
              src="./assets/ic_delete.svg"
              @click="removeItem(item.id)"
            />
            <span>{{ item.name }}</span>
            <img class="handle" src="./assets/ic_items.svg" />
          </div>
        </VueDraggable>
      </div>
      <!-- 默認(rèn)子項 -->
      <div class="change-sort">
        <span class="label" style="margin-top: 24px">默認(rèn)子項</span>
        <div
          class="sort-item"
          v-for="item in constList"
          :key="item.id"
          :style="sortList.find((el) => el.id === item.id) ? 'opacity:0.3' : ''"
        >
          <img
            class="add"
            src="./assets/ic_add.svg"
            @click="addItem(item.id)"
          />
          <span>{{ item.name }}</span>
        </div>
      </div>
    </div>
    <div class="sheet-footer">
      <van-button>取消</van-button>
      <van-button type="primary" @click="onConfirm">保存</van-button>
    </div>
  </van-action-sheet>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { type UseDraggableReturn, VueDraggable } from "vue-draggable-plus";
interface SortItemType {
  name: string;
  id: number;
}
// 當(dāng)前排列項
let sortList = ref<SortItemType[]>([
  { id: 1, name: "Vue" },
  { id: 2, name: "React" },
  { id: 3, name: "TypeScript" },
  { id: 4, name: "Uniapp" },
  { id: 5, name: "Vite" },
]);
// 對比項(內(nèi)容不變,作為參照與sortList進行對比)
let constList = ref<SortItemType[]>([
  { id: 2, name: "React" },
  { id: 3, name: "TypeScript" },
  { id: 4, name: "Uniapp" },
  { id: 5, name: "Vite" },
]);
const sortShow = ref(false);
const el = ref<UseDraggableReturn>();
const disabled = ref(false);
const onStart = () => {
  console.log("拖拽前-sortList:", sortList.value);
};
?
const onUpdate = () => {
  console.log("拖拽后-sortList:", sortList.value);
};
?
const sortClick = () => {
  sortShow.value = true;
};
/**
 * 移除當(dāng)前排列項
 */
const removeItem = (id: number) => {
  if (id === 1) return; // 默認(rèn)不能刪除
  let idx = sortList.value.findIndex((item: SortItemType) => item.id === id);
  if (idx !== -1) {
    sortList.value.splice(idx, 1);
  }
};
/**
 * 新增排列項
 */
const addItem = (id: number) => {
  let idx = sortList.value.findIndex((item: SortItemType) => item.id === id);
  if (idx === -1) {
    sortList.value.push(
      constList.value.find((item: SortItemType) => item.id === id),
    );
  }
};
/**
 * 保存當(dāng)前排序
 */
const onConfirm = () => {
  sortList.value.map((item: any, index: number) => {
    item.sortOrder = index + 1;
  });
  sortShow.value = false;
};
</script>
?
<style lang="less" scoped>
.content {
  .label {
    display: block;
    font-weight: 600;
    font-size: 13px;
    color: #969799;
    height: 18px;
    padding-left: 16px;
    margin-bottom: 16px;
  }
  .sort-item {
    margin-bottom: 16px;
    font-weight: 600;
    font-size: 15px;
    color: #323233;
    position: relative;
    .delete,
    .add {
      vertical-align: middle;
      margin: 0 12px 0 19px;
    }
    .handle {
      vertical-align: middle;
      position: absolute;
      right: 15px;
    }
  }
}
.sheet-footer {
  display: flex;
  justify-content: center;
  padding: 10px;
  .van-button {
    width: 165px;
    height: 40px;
    margin: 0 6px;
  }
}
</style>
?

最終實現(xiàn)效果圖

以上就是使用vue-draggable-plus實現(xiàn)拖拽排序的詳細內(nèi)容,更多關(guān)于vue-draggable-plus拖拽排序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解vue3.0 的 Composition API 的一種使用方法

    詳解vue3.0 的 Composition API 的一種使用方法

    這篇文章主要介紹了vue3.0 的 Composition API 的一種使用方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Vue的computed計算屬性你了解嗎

    Vue的computed計算屬性你了解嗎

    這篇文章主要為大家詳細介紹了Vue的computed計算屬性,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • vue3?錨點定位的多種實現(xiàn)方式

    vue3?錨點定位的多種實現(xiàn)方式

    這篇文章主要介紹了vue3?多種方法的錨點定位,使用?Vue?Router?導(dǎo)航守衛(wèi)可以簡化導(dǎo)航邏輯、統(tǒng)一管理導(dǎo)航邏輯和進行權(quán)限控制,但需要學(xué)習(xí)和理解相關(guān)概念,并且需要手動編寫和管理導(dǎo)航守衛(wèi)的邏輯,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Vue3中各種靈活傳遞數(shù)據(jù)的方式小結(jié)

    Vue3中各種靈活傳遞數(shù)據(jù)的方式小結(jié)

    Vue 3 提供了多種數(shù)據(jù)傳遞的方式,讓我們的組件之間可以盡情地交流,接下來,我們就直接一個個來看,這些方式都是怎么工作的,感興趣的小伙伴跟著小編一起來看看吧
    2024-07-07
  • 如何重置vue打印變量的顯示方式

    如何重置vue打印變量的顯示方式

    這篇文章主要給大家介紹了關(guān)于如何重置vue打印變量顯示方式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。
    2017-12-12
  • VUE項目IIS部署使用nginx代理訪問后端接口方式

    VUE項目IIS部署使用nginx代理訪問后端接口方式

    文章瀏覽閱讀704次。文章講述了項目使用vue-element-admin遇到的跨域問題,嘗試了瀏覽器JS、打包路徑、路由模式和IIS代理等方法均無效,最終通過配置Nginx進行后端接口代理解決了問題,同時提供了參考文檔鏈接。
    2025-12-12
  • vue router2.0二級路由的簡單使用

    vue router2.0二級路由的簡單使用

    這篇文章主要為大家詳細介紹了vue router2.0二級路由的簡單使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 自帶氣泡提示的vue校驗插件(vue-verify-pop)

    自帶氣泡提示的vue校驗插件(vue-verify-pop)

    這篇文章主要為大家詳細介紹了自帶氣泡提示的vue校驗插件,vue-verify-pop的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Vue+Bootstrap實現(xiàn)簡易學(xué)生管理系統(tǒng)

    Vue+Bootstrap實現(xiàn)簡易學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Vue+Bootstrap實現(xiàn)簡易學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • vue父組件調(diào)用子組件方法報錯問題及解決

    vue父組件調(diào)用子組件方法報錯問題及解決

    這篇文章主要介紹了vue父組件調(diào)用子組件方法報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評論

雅江县| 平湖市| 梁山县| 衡东县| 红桥区| 丰镇市| 黄山市| 中宁县| 沁水县| 沁源县| 会同县| 朝阳县| 隆昌县| 太原市| 图片| 昆山市| 武功县| 社旗县| 英吉沙县| 江城| 图片| 牡丹江市| 江门市| 宜兴市| 淳安县| 兰考县| 同德县| 大庆市| 宜宾县| 孟津县| 嘉鱼县| 德钦县| 平顺县| 彭山县| 湟中县| 新野县| 临夏县| 新沂市| 门头沟区| 从江县| 汝州市|