Praktische Verwendung von vuedraggable: Kombinieren spezifischer Anwendungsszenarien, um Drag-and-Drop-Sortierung innerhalb von Listen, Bewegung zwischen Listen, Kopieren, Einführung, Installation, Verwendung, Fallstricke und Lösungen zu realisieren

Hintergrund

Lassen Sie uns zunächst über die Anforderungen sprechen. Um die Entwicklungseffizienz zu verbessern und Entwicklungskosten und technische Schwierigkeiten zu reduzieren, werden Low-Code-Methoden verwendet, um Code durch Konfiguration zu generieren, bei der es sich um eine aktualisierte Lösung des Codegenerators handelt.

Für die Front-End-Seite entspricht eine bestimmte Geschäftseinheit, z. B. Systemparameter, einem gemeinsamen Menü einer Listenseite mit Funktionsschaltflächen auf Seitenebene oben, z. B. Hinzufügen, Löschen, Exportieren usw., und einer Abfrage Bereich in der Mitte, in dem mehrere häufig verwendete Abfragebedingungen platziert werden können. Unten befinden sich die Abfrageergebnisse, in denen Zeilen- und Spaltendaten in Tabellenform angezeigt werden. Um den Benutzerbetrieb zu erleichtern, werden außerdem häufig die Zeilendatensätze der Ergebnistabelle abgefragt und in der letzten Spalte einige Verknüpfungsschaltflächen für die Zeilendaten platziert, z. B. Löschen, Bearbeiten usw., wie in der Abbildung dargestellt unten

Fügen Sie hier eine Bildbeschreibung ein

Hinweis: In der obigen Abbildung sind die Funktionsschaltflächen auf Seitenebene zwischen dem Abfragebereich und den Abfrageergebnissen platziert.

Um die Konfiguration der obigen Seite zu realisieren, müssen vier konfigurierbare Bereiche abstrahiert und unterteilt werden, nämlich Seitenschaltflächen, Abfragebedingungen, Abfragelisten und Zeilenschaltflächen. Die Darstellung ist wie folgt:

Fügen Sie hier eine Bildbeschreibung ein

In Bezug auf technische Lösungen wird durch Konfigurations- und Vorlagentechnologie die automatische Generierung von Front-End-Code für Listenansichtsseiten erreicht.

Die obige Konfigurationsfunktion umfasst einerseits das Sortieren von Elementen, wie z. B. die Reihenfolge von Schaltflächen, die Reihenfolge von Abfragebedingungen und die Reihenfolge von Spalten in Abfrageergebnissen, andererseits das Verschieben von Elementen zwischen Listen, wie z. B. das Hinzufügen von Entitätsattributen zur Abfrage. in der Liste oder den Abfrageergebnissen. Wenn Sie den herkömmlichen Modus verwenden, müssen Sie ein Element auswählen und auf die Schaltflächen „Nach links verschieben“, „Nach rechts verschieben“ und andere Schaltflächen klicken, was nicht intuitiv ist und die Bedienung umständlich ist. Durch den Drag-and-Drop-Vorgang erhalten Sie genau das, was Sie sehen, und das Benutzererlebnis wird erheblich verbessert.

Element UI bietet die meisten UI-Steuerelemente, ist jedoch in der Tat ein Nachteil für Drag & Drop, sodass zusätzliche Steuerelemente erforderlich sind, um es zu ergänzen, nämlich das vuedraggable des heutigen Protagonisten.

Einführung

Draggable ist eine auf Sortable.js basierende Vue-Komponente, die zur Implementierung von Drag-and-Drop-Funktionen verwendet wird.

charakteristisch
  • Unterstützt Touch-Geräte
  • Unterstützt das Ziehen und Auswählen von Text
  • Unterstützt intelligentes Scrollen
  • Unterstützt Drag & Drop zwischen verschiedenen Listen
  • Basiert nicht auf jQuery
  • Synchron mit dem Ansichtsmodell aktualisieren
  • Kompatibel mit vue2-Übergangsanimation
  • Unterstützen Sie den Rückgängig-Vorgang
  • Wenn vollständige Kontrolle erforderlich ist, können alle Änderungen übernommen werden
  • Kompatibel mit vorhandenen UI-Komponenten

Offizielle Adresse: https://github.com/SortableJS/Vue.Draggable
Dokumentation der chinesischen Version: https://www.itxst.com/vue-draggable/tutorial.html

Installieren

npm install vuedraggable -S

Zitat

Importiere Draggable aus 'vuedraggable'

Tatsächlicher Kampf

Als nächstes werde ich vorstellen, wie wir unsere Funktionen aus praktischer Sicht implementieren, welche Schlüsselattribute und Methoden verwendet werden, welche Punkte Aufmerksamkeit erfordern, Fallstricke und Lösungen.

Zum Sortieren ziehen

Am Beispiel von Funktionsschaltflächen auf Seitenebene ist der Effekt wie folgt:
Fügen Sie hier eine Bildbeschreibung ein

Der Front-End-Quellcode lautet wie folgt:

<template>
  <el-row :gutter="20" type="flex">
    <el-col :span="24">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>页面按钮配置</span>
          <span style="float:right">
            <el-button style=" padding: 1px 0" icon="el-icon-plus" @click="add" />
            <el-button style=" padding: 1px 0" icon="el-icon-delete" @click="clear" />
          </span>
        </div>
        <draggable v-model="buttonList" :group="group" @sort="updateSort" @update="update">

          <el-row v-for="(item) in buttonList" :key="item.code">
            <el-col>
              <el-tag closable @close="remove(item.id)" @click="modify(item.id)"> {
   
   { item.name }}</el-tag>

            </el-col>
          </el-row>

        </draggable>

        <detail ref="detail" :custom-parent-id="this.$route.query.id" :button-type="$constant.BUTTON_TYPE_PAGE" @ok="handleDetailSave" />
      </el-card>
    </el-col>

  </el-row>

</template>

<script>
import Detail from './detail'
import Draggable from 'vuedraggable'
export default {
  components: { Detail, Draggable },
  data() {
    return {
      entityViewId: '',
      buttonList: [],
      group: {
        name: 'pageButton',
        pull: false,
        put: false
      }
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.entityViewId = this.$route.query.id
      this.query()
    },
    // 新增
    add() {
      this.$refs.detail.add()
    },
    // 修改
    modify(id) {
      this.$refs.detail.modify(id)
    },
    // 移除
    remove(id) {
      this.$confirm('此操作将移除页面按钮, 是否继续?', '确认', {
        type: 'warning'
      }).then(() => {
        this.$api.entityconfig.entityViewButton.remove(id)
          .then(() => {
            this.query()
          })
      }).catch(() => {
        this.$message.info('已取消')
      })
    },
    // 清空
    clear(id) {
      this.$confirm('此操作将移除所有页面按钮,已配置信息丢失且不可恢复,是否继续?', '确认', {
        type: 'warning'
      }).then(() => {
        this.$api.entityconfig.entityViewButton.clear(id)
          .then(() => {
            this.query()
          })
      }).catch(() => {
        this.$message.info('已取消')
      })
    },

    // 加载按钮列表
    query() {
      this.$api.entityconfig.entityViewButton.listByViewAndType(this.entityViewId, this.$constant.BUTTON_TYPE_PAGE).then(res => {
        this.buttonList = res.data
      })
    },

    // 更新次序
    updateSort(evt) {
      evt.preventDefault()
      const sortedButtonList = this.buttonList.map(function (value, index) {
        return { 'index': index, 'code': value.code }
      })
      this.$api.entityconfig.entityViewButton.updateButtonSort(this.entityViewId, sortedButtonList)
    },
    handleDetailSave() {
      this.query()
    }
  }

}

</script>

<style>

</style>

Dies kombiniert verschiedene Steuerelemente der Element-Benutzeroberfläche, einschließlich el-row, el-col, el-card und el-tag. Der Kerncode für vuedraggable lautet wie folgt:

 <draggable v-model="buttonList" :group="group" @update="updateSort">
    <el-row v-for="(item) in buttonList" :key="item.code">
      <el-col>
        <el-tag closable @close="remove(item.id)" @click="modify(item.id)"> {
   
   { item.name }}</el-tag>
      </el-col>
    </el-row>
  </draggable>

Das Schlüsselattribut ist das V-Modell, das an ein Objektarray gebunden ist, das die Datenquelle der Komponente darstellt. Dies ist die Standardpraxis von Vue, und es gibt nichts zu sagen.
Was das Gruppenattribut betrifft: Wenn Sie diese Komponente allein betrachten, müssen Sie es nicht festlegen. Wenn Sie es jedoch nicht global festlegen, gibt es Fallstricke. Ich werde später darauf eingehen, aber Sie können es ignorieren hier.

Es gibt zwei Ereignisse im Zusammenhang mit der Sortierung in Komponenten: eines ist „Update“ und das andere ist „Sort“. Welches sollten wir verwenden?
Es ist schwierig, den Unterschied zur offiziellen Beschreibung zu erkennen: update: ein Ereignis, das ausgelöst wird, wenn das Ziehen die Position ändert; sort: ein Ereignis, das ausgelöst wird, wenn sich die Position ändert.
Ich habe es selbst getestet. Im aktuellen Szenario können beide Ereignisse durch Ziehen von Elementen ausgelöst werden, um die Reihenfolge zu ändern. Wenn Elemente zum Datenquellenarray hinzugefügt oder daraus gelöscht werden, wird keines der Ereignisse ausgelöst. In diesem Szenario kann jedes beliebige Ereignis verwendet werden. Das Aktualisierungsereignis wird hier ausgewählt.

  // 更新次序
    updateSort(evt) {
      evt.preventDefault()
      const sortedButtonList = this.buttonList.map(function (value, index) {
        return { 'index': index, 'code': value.code }
      })
      this.$api.entityconfig.entityViewButton.updateButtonSort(this.entityViewId, sortedButtonList)
    },

Der Zweck von evt.preventDefault() besteht darin, zu verhindern, dass einige Browser, wie z. B. Firefox, das Ziehen als Download behandeln.
Vuedraggable übernimmt die Front-End-Sortierarbeit und muss schließlich zur Verarbeitung an das Back-End übergeben werden. Daher verarbeiten die folgenden Zeilen die eindeutige Datenkodierung und den aktuellen Indexwert in einem Objektarray und übergeben sie an das Backend, das die Sortiernummer aktualisiert, um die Reihenfolgenanpassung beizubehalten.

Zwischen Listen ziehen

Das Implementierungseffektdiagramm lautet wie folgt:
Fügen Sie hier eine Bildbeschreibung ein

Dies ist eigentlich eine Kombination aus drei vetragbaren Komponenten. Der äußerste Teil sieht so aus:

<template>
  <el-row :gutter="20" type="flex">
    <el-col :span="5"> <page-button /></el-col>
    <el-col :span="5"> <property-list @getAllPropertyData="getAllPropertyData" @refreshQueryCondition="refreshQueryCondition" @refreshQueryResult="refreshQueryResult" /></el-col>
    <el-col :span="9">
      <el-row :gutter="20" type="flex">
        <el-col :span="24">  <query-area ref="queryCondition" :property-list-data="allPropertyList" /></el-col>
      </el-row>
      <el-row :gutter="20" type="flex">
        <el-col :span="24">  <result-area ref="queryResult" :property-list-data="allPropertyList" /></el-col>
      </el-row>
    </el-col>
    <el-col :span="5"> <row-button /></el-col>
  </el-row>

</template>

Jeder Bereich wurde in eine unabhängige Vue-Seite aufgeteilt. Am Anfang hatte ich Bedenken, dass diese Art der Elementverschiebung zwischen seitenübergreifenden Listen möglicherweise nicht unterstützt wird. Ich habe es tatsächlich getestet und festgestellt, dass es kein Problem gab, was gut ist.

Wenn Sie zwischen Listen ziehen möchten, müssen Sie laut offizieller Dokumentation das Gruppenattribut festlegen. Eine Gruppe kann ein einzelnes Attribut oder ein Objekt sein. Die Namensattribute der Objekte müssen gleich sein.

//设置方式一,直接设置组名
group:'list'

//设置方式二,object,也可以通过自定义函数function实现复杂的逻辑
group:{
    name:'list',
    pull: true|false| 'clone'|array|function,//是否允许拖出当前组
    put:true|false|array|function,//是否允许拖入当前组
}

In meinem Design wird die Entitätsattributliste aus der Entitätskonfiguration gelesen und kann sowohl zur Abfragebedingungsliste oben rechts als auch zur Abfrageergebnisliste unten rechts hinzugefügt werden. Die Einstellungen lauten also wie folgt:

allPropertyGroup: {
    name: 'list',
    pull: 'clone',
    put: false
  }

name ist der Gruppenname, put ist false, um das Hinzufügen von Elementen durch Ziehen zu deaktivieren.
Beachten Sie, dass der Pull-Attributwert im aktuellen Szenario auf „Klonen“ eingestellt sein muss, was bedeutet, dass das aktuelle Element kopiert und in der Zielliste platziert wird. Wenn es auf „true“ gesetzt ist, entspricht es dem Verschieben; wenn es auf „false“ gesetzt ist, ist es äquivalent um das Ziehen aus der aktuellen Liste zu deaktivieren.

Abfragebedingungen und Abfrageergebnisse sind im Wesentlichen gleich. Ich verwende Abfragebedingungen als Beispiel, um zu veranschaulichen, wie Elemente empfangen werden, die aus der Entitätsattributliste auf der linken Seite gezogen werden.

<draggable v-model="queryConditionList" :group="group" style="height:200px" @add="addFromModelProperty" @update="updateSort">
          <el-row v-for="(item) in queryConditionList" :key="item.code">
            <el-col> <el-tag closable @close="remove(item.id)" @click="modify(item.id)">{
   
   { item.name }}</el-tag>
            </el-col>
          </el-row>
        </draggable>

Legen Sie zunächst das Gruppenattribut fest. Der Name sollte mit der Liste auf der linken Seite übereinstimmen, die beide als Liste bezeichnet werden. Pull ist auf false gesetzt, um das Ziehen aus der aktuellen Liste zu verhindern. Zu diesem Zeitpunkt sollte put mit true angegeben werden, was bedeutet, dass dies der Fall ist akzeptiert das Einziehen.

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

Dann ist das Schlüsselereignis add, ein Ereignis, das nach dem Ziehen ausgelöst wird. Es ist zu beachten, dass der von diesem Ereignis getragene evt-Parameter zwar sehr groß ist, die darin platzierten Dinge jedoch Front-End-UI-Elemente sind und nicht die von uns erwarteten Daten . Ich hoffe beispielsweise, die Kodierung der Entitätsattribute zu erhalten. Durch diese Kodierung kann ich die Entitätsattribute finden, dann andere verwandte Daten kopieren und in die Bibliothekstabelle der Abfrageliste einfügen. Ich kann diese Informationen nicht aus dem evt erhalten Parameter.
Zu diesem Zeitpunkt gelang es durch Kurven, das Land zu retten. Aus dem evt-Parameter können wir den Index oldIndex der Quellliste des gezogenen Elements abrufen. Auf diese Weise können wir in Kombination mit dem gebundenen Datenobjekt der Quellliste die erwarteten Daten erhalten.

// 新增
    addFromModelProperty(evt) {
      const code = this.propertyListData[evt.oldIndex].code
      this.$api.entityconfig.viewQueryCondition.addFromModelProperty(this.entityViewId, code)
        .then(() => this.sort())
    },

In diesem Szenario können Sie den Unterschied zwischen dem Sortierereignis und dem Aktualisierungsereignis testen. Wenn Sie ein Element aus einer anderen Liste ziehen, wird nur das Sortierereignis ausgelöst, die Aktualisierung wird jedoch nicht ausgelöst. Mit anderen Worten: Das Aktualisierungsereignis wird nur ausgelöst, wenn durch Ziehen innerhalb der Liste die Reihenfolge geändert wird, und die Sortierung wird auch ausgelöst, wenn ein Element hineingezogen wird.

Da die Sortierung mehr Auslösemöglichkeiten bietet, warum verwende ich nicht die Sortierung, sondern trotzdem die Aktualisierung?
Da die Sortierung in unserem Szenario problematisch ist, ziehen wir die Entitätsattribute aus der Attributliste links in die Abfragebedingungen rechts. Die logische Verarbeitung besteht darin, zunächst die Attribute zu kopieren und eine neue Zeile mit Datensätzen in den Abfragebedingungen basierend darauf zu erstellen die Kodierung. Das Sortierereignis wird ausgelöst, sobald das gezogene Objekt abgelegt wird, und dann werden die aktuelle Attributliste und der Indexwert übergeben. Zu diesem Zeitpunkt ist die Dateneinfügungsaktion noch nicht abgeschlossen und die Sortiernummer wird aktualisiert Das neu gezogene Element meldet eine Ausnahme, dass das Objekt nicht existiert. .
Wie man es löst? Tatsächlich ist es auch einfach: Wir verwenden keine Sortierung. Einerseits verwenden wir weiterhin Update, um die Drag-Sortierung innerhalb der Liste zu handhaben. Andererseits können wir im Add-Ereignis neue Elemente durch Ziehen hinzufügen Promise-Funktion: Nachdem die Dateneinfügung erfolgreich verarbeitet wurde, rufen wir eine Backend-Operation auf, die die Sequenz aktualisiert.

// 新增
    addFromModelProperty(evt) {
      const code = this.propertyListData[evt.oldIndex].code
      this.$api.entityconfig.viewQueryCondition.addFromModelProperty(this.entityViewId, code)
        .then(() => this.sort())
        }
    },

    // 拖拽结束
    updateSort(evt) {
      evt.preventDefault()
      this.sort()
    },
    // 排序
    sort() {
      const sortedList = this.queryConditionList.map(function (value, index) {
        return { 'index': index, 'code': value.code }
      })
      this.$api.entityconfig.viewQueryCondition.updateSort(this.entityViewId, sortedList)
    },

Im Anhang finden Sie den vollständigen Quellcode des Abfragebedingungsbereichs als Referenz.

<template>

  <el-row :gutter="20">
    <el-col :span="24">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>查询条件</span>
          <span style="float:right">
            <el-button style=" padding: 1px 0" icon="el-icon-plus" @click="add" />
            <el-button style=" padding: 1px 0" icon="el-icon-delete" @click="clear" />

          </span>
        </div>
        <draggable v-model="queryConditionList" :group="group" style="height:200px" @add="addFromModelProperty" @update="updateSort">
          <el-row v-for="(item) in queryConditionList" :key="item.code">
            <el-col> <el-tag closable @close="remove(item.id)" @click="modify(item.id)">{
   
   { item.name }}</el-tag>
            </el-col>
          </el-row>
        </draggable>
      </el-card>
      <detail ref="detail" :custom-parent-id="this.$route.query.id" @ok="handleDetailSave" />
    </el-col>

  </el-row>

</template>

<script>
import Detail from './detail'
import Draggable from 'vuedraggable'

export default {
  components: { Detail, Draggable },
  props: {
    propertyListData: {
      type: Array,
      default: () => [],
      required: false

    }},
  data() {
    return {
      entityViewId: '',
      queryConditionList: [],
      currentConditionId: '',
      group: {
        name: 'list',
        pull: false,
        put: true
      }
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.entityViewId = this.$route.query.id

      this.query()
    },
    // 新增
    add() {
      this.$refs.detail.add()
    },
    // 新增
    addFromModelProperty(evt) {
      const code = this.propertyListData[evt.oldIndex].code
      this.$api.entityconfig.viewQueryCondition.addFromModelProperty(this.entityViewId, code)
        .then(() => this.sort())
    },
    // 修改
    modify(id) {
      this.currentConditionId = id
      this.$refs.detail.modify(this.currentConditionId)
    },
    // 移除
    remove(queryConditionId) {
      this.$confirm('此操作将移除查询条件, 是否继续?', '确认', {
        type: 'warning'
      }).then(() => {
        this.$api.entityconfig.viewQueryCondition.remove(queryConditionId)
          .then(() => {
            this.query()
          })
      }).catch(() => {
        this.$message.info('已取消')
      })
    },

    // 加载列表
    query() {
      this.$api.entityconfig.viewQueryCondition.listByView(this.entityViewId).then(res => {
        this.queryConditionList = res.data
      })
    },
    // 拖拽结束
    updateSort(evt) {
      evt.preventDefault()
      this.sort()
    },
    // 排序
    sort() {
      const sortedList = this.queryConditionList.map(function (value, index) {
        return { 'index': index, 'code': value.code }
      })
      this.$api.entityconfig.viewQueryCondition.updateSort(this.entityViewId, sortedList)
    },
    // 清空
    clear() {
      this.$confirm('此操作将移除所有查询条件,已配置信息丢失且不可恢复,是否继续?', '确认', {
        type: 'warning'
      }).then(() => {
        this.$api.entityconfig.viewQueryCondition.clear(this.entityViewId)
          .then(() => {
            this.query()
          })
      }).catch(() => {
        this.$message.info('已取消')
      })
    },
    handleDetailSave() {
      this.query()
    }
  }

}

</script>

<style>
.el-row {
    margin-bottom: 10px;
  }

</style>

Als nächstes stehen wir vor dem Problem, wie wir mit der wiederholten Hinzufügung von Attributen umgehen sollen.
Solange Sie vuedraggable per Drag & Drop verschieben, können Sie den Effekt sofort sehen. Ziehen Sie beispielsweise die Abfragebedingungen per Drag & Drop aus der Entitätsattributliste links nach rechts. In diesem Szenario muss jedoch tatsächlich festgestellt werden, ob die Attributliste auf der rechten Seite bereits vorhanden ist. Wenn sie nicht vorhanden ist, darf sie hinzugefügt werden. Wenn sie vorhanden ist, wird sie nicht hinzugefügt. Die Überprüfungsverarbeitung im Back-End ist ein kleiner Fall, daher werde ich hier nicht auf Details eingehen. Der Schlüssel liegt darin, wie man sie im Front-End handhabt.

Nachdem ich die offiziellen Dokumente lange gelesen hatte, konnte ich keine geeignete Steuerung finden. Ich habe auch lange auf Baidu gesucht, aber es gab kein zufriedenstellendes Ergebnis. Nachdem ich es selbst erkundet hatte, fand ich schließlich heraus, dass das Move-Ereignis dies kann verwendet werden. Tatsächlich wird die offizielle Positionierung des Verschiebens verwendet, um anzupassen und zu steuern, welche Elemente gezogen werden können oder nicht, und um zu steuern, ob das Andocken zulässig ist. Was wir hier wollen, ist zu steuern, ob das Andocken erlaubt ist.

//move回调方法
onMove(e,originalEvent){ 
         console.log(e);
         console.log(originalEvent);
         //false表示阻止拖拽
         return true;
  },  

Eine Gefahr besteht zunächst darin, dass move zwar ein Ereignis ist, aber nicht durch @move='move' ausgelöst wird. Stattdessen wird die Attributbindung mit :move='move' verwendet, was etwas kontraproduktiv ist. Gesunder Menschenverstand, Ich steckte eine Weile fest und stellte fest, dass das Ereignis nicht ausgelöst wurde. Nachdem ich die Dokumentation im Detail gelesen hatte, stellte ich fest, dass das Problem hier lag.

Zweitens ist in unserem Szenario das Verschiebungsattribut an die Entitätsattributkomponente auf der linken Seite oder die Abfragebedingungskomponente auf der rechten Seite gebunden. Aus der Beschreibung, ob Andocken zulässig ist, geht hervor, dass es auf der rechten Seite platziert werden sollte. Allerdings Bei tatsächlichen Tests wurde festgestellt, dass das Ziehen von links nach rechts überhaupt nicht ausgelöst wird, sodass diese Verschiebung tatsächlich für die Quellliste gilt.

Auch hier stellte der eigentliche Test fest, dass es ein Problem mit der mehrfachen Auslösung gab. Es wurde vermutet, dass es mit dem Event-Bubbling-Mechanismus des Frontends zusammenhängt. Nach langer Suche konnte ich immer noch keine Möglichkeit finden, es auszulösen nur einmal. Wenn jemand dieses Loch ausgefüllt hat, sagen Sie mir bitte in den Kommentaren, wie ich damit umgehen soll. Vielen Dank im Voraus.

// 移动
    move(e) {
      // TODO 存在触发多次问题    
      const code = e.draggedContext.element.code
      const list = e.relatedContext.list
      const exist = list.some(item => { return item.code === code })
      // if (exist) {
      //   this.$message.info('已存在,请勿重复添加')
      // }


      return !exist
    }

Das Gute an diesem Ereignis ist, dass die erwarteten Daten aus den Ereignisparametern abgerufen werden können, z. B. e.draggedContext.element, das das an das gezogene Element gebundene Datenobjekt abrufen kann, und e.latedContext.list, das das abrufen kann Daten der Zielliste. , kann ein einfacher Vergleich zwischen den beiden feststellen, ob es sich um eine wiederholte Hinzufügung handelt. Wenn ja, gibt die Methode false zurück und der Ziehvorgang kann beendet werden.

17.04.2023 Optimieren Sie das mehrfache Auslösen von Bewegungen
. Die Drittanbieter-Toolklasse Throttle wird eingeführt, um die Anzahl der Auslöser von Bewegungen zu begrenzen. Weitere Informationen finden Sie im Blog-Beitrag https://blog.csdn.net/seawaving/article/ Details/130157163

import {
    
     throttle } from 'lodash';

export default {
    
    
  methods: {
    
    
    handleMove: throttle(function(event) {
    
    
      // 处理拖动事件
    }, 100)
  }
}

Ich ging
zurück und dachte über dieses Problem nach. Wenn ich das Ziehen von Eigenschaften zwischen Listen vom Stamm aus realisieren und den Effekt nur einmal auslösen möchte, sollte die vuedraggable-Komponente das entsprechende Ereignis bereitstellen, d. h. nach dem Ziehen in die Liste die linke Maustaste loslassen angegebene Position. ausgelöst, wenn.

Die vuedraggable-Komponente verfügt über ein Endereignis, aber dieses Ereignis ähnelt nicht dem Verschieben. Die Rückgabe von false kann den Vorgang abbrechen, ist aber auf jeden Fall erfolgreich. Das heißt, ziehen Sie vom Frontend aus ein Attribut aus der linken Liste in die rechte Liste, unabhängig davon davon, ob die richtige Liste vorhanden ist. Obwohl Sie es vom Back-End aus überprüfen und verarbeiten und die Liste auf der rechten Seite aktualisieren können, ist es unvermeidlich, dass es zu einem Flackern kommt, das zuerst erscheint und dann verschwindet, und der Effekt ist nicht gut.

Ursprünglich wurde festgestellt, dass das Endereignis das Ziehen nicht abbrechen kann, daher wurde „Move“ als kurvensparende Lösung verwendet. Daher besteht die derzeit optimale Lösung darin, die Anzahl der Auslöser mithilfe der Drosselfunktion zu verringern. Nach wiederholten Versuchen ist es angemessener, das Intervall auf 500 Millisekunden einzustellen, wodurch die Anzahl der Auslöser erheblich reduziert werden kann, ohne dass der Ziehvorgang angezeigt wird verzögert.

Ich hoffe übrigens, dass die vuedraggable-Komponente in Zukunft das Endereignis in ein stornierbares umwandeln kann, sodass dieses Problem perfekt gelöst werden kann.

Lassen Sie uns abschließend über eine unerwartete Gefahr sprechen. Laut dem offiziellen Dokument müssen Sie beim Ziehen zwischen verschiedenen Listen das Gruppenattribut festlegen und sicherstellen, dass das Namensattribut konsistent ist. Allerdings ... während des Testvorgangs habe ich das versehentlich entdeckt Ich kann tatsächlich die Seitenebene ändern. Die Schaltfläche wurde per Drag & Drop in die Abfragebedingungsliste gezogen, aber die Gruppennamen waren offensichtlich unterschiedlich ... Später musste ich die Komponente der Seitenschaltfläche patchen und verhindern, dass ihre Elemente herausgezogen werden die Liste zur Lösung dieses Problems.

group: {
        name: 'pageButton',
        pull: false,
        put: false
      }

08.12.2022 Ein neuer Fehler wurde getestet, bitte geben Sie eine zusätzliche Erklärung.
Wählen Sie aus der Entitätsattributliste ein Attribut aus und ziehen Sie es in die Abfragebedingungsliste. Dieser Schritt funktioniert normal. Wenn Sie jedoch auf das neu hinzugefügte Attribut in der Abfragebedingungsliste klicken und das Bearbeitungsfenster öffnen, wird eine Fehlermeldung angezeigt, dass die Daten nicht gefunden werden können wird gemeldet. Nach der Fehlerbehebung liegt das Problem im ID-Feld. Die ID des gezogenen Feldes ist ein Entitätsattribut. Beim Platzieren in der neuen Liste hat sich die ID nicht geändert. Die Bearbeitungsseite in der Abfragebedingungsliste wird jedoch verwendet die ID, um die Daten abzurufen Es besteht das Problem, dass das Objekt nicht gefunden werden kann ... Diese Grube ist relativ versteckt.

Der Grund ist gefunden und die Lösung ist relativ einfach: Rufen Sie in der Sortiermethode die Abfrageschnittstelle erneut auf, rufen Sie die Daten von der Fernbedienung ab und überschreiben Sie die Datenquelle der Liste.


    // 排序
    sort() {
    
    
      const sortedList = this.queryConditionList.map(function (value, index) {
    
    
        return {
    
     'index': index, 'code': value.code }
      })
      this.$api.entityconfig.viewQueryCondition.updateSort(this.entityViewId, sortedList).then(() => {
    
    
        this.query()
      })
    },
   // 加载列表
    query() {
    
    
      this.$api.entityconfig.viewQueryCondition.listByView(this.entityViewId).then(res => {
    
    
        this.queryConditionList = res.data
      })
    },
 

Supongo que te gusta

Origin blog.csdn.net/seawaving/article/details/128083596
Recomendado
Clasificación