Я использую vuedraggable в проекте Vue 3, чтобы разрешить изменение порядка элементов внутри панели расширения. Элементы можно перетаскивать в новое положение на панели, но при отпускании они возвращаются в исходное положение. Я подозреваю, что базовый список, используемый vuedraggable, не обновляется при перемещении элементов, что приводит к их возврату в исходное положение. Вот соответствующая часть моего кода:
<v-expansion-panels>
<v-expansion-panel v-for = "feature in groupedFeatures" :key = "feature.type">
<v-expansion-panel-title>
<div>{{ translateFeatureType(feature.type) }}</div>
</v-expansion-panel-title>
<v-expansion-panel-text>
<draggable v-model = "feature.details" group = "featureGroup" item-key = "model_name">
<template #item = "{element, index}">
<div :key = "element.model_name">
<p><strong>Model:</strong> {{ element.model_name }}</p>
<p>{{ element.value }}</p>
</div>
</template>
</draggable>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
Мой импорт:
import { ref, onMounted, computed } from 'vue';
import axios from 'axios';
import { useRoute } from 'vue-router';
import draggable from 'vuedraggable';
const route = useRoute();
const features = ref([]);
const messages = ref([]);
Функция onMounted:
onMounted(async () => {
const threadData = await fetchEmailThreads(route.params.id);
if (threadData) {
features.value = threadData.features;
messages.value = threadData.messages;
}
И функция groupedFeatures
const groupedFeatures = computed(() => {
const featureMap = new Map();
features.value.forEach(f => {
if (!featureMap.has(f.type)) {
featureMap.set(f.type, { type: f.type, details: [] });
}
featureMap.get(f.type).details.push({ model_name: f.model_name, value: f.value });
});
return Array.from(featureMap.values());
});
Вот как выглядят данные, предоставленные сервером:
{
"chat_id": 1,
"features": [
{
"model_name": "Vicuna-13B",
"type": "abstract_feature",
"value": "---Feature Content---"
},
{
"model_name": "Vicuna-13B",
"type": "generated_feature",
"value": "---Feature Content---"
},
{
"model_name": "Vicuna-13B",
"type": "generated_feature",
"value": "---Feature Content---"
},
{
"model_name": "Vicuna-13B",
"type": "order_feature",
"value": "---Feature Content---"
},
{
"model_name": "Solaris-13B",
"type": "abstract_feature",
"value": "---Feature Content---"
},
{
"model_name": "Solaris-13B",
"type": "generated_feature",
"value": "---Feature Content---"
},
{
"model_name": "Solaris-13B",
"type": "generated_feature",
"value": "---Feature Content---"
},
{
"model_name": "Solaris-13B",
"type": "order_feature",
"value": "---Feature Content---"
}
],
"inst_id": 0,
"messages": [
{
"content": "Message Content...",
"message_id": 1,
"sender": "sender1",
"timestamp": "2022-11-08T14:15:00"
},
{
"content": "Message Content...",
"message_id": 2,
"sender": "sender2",
"timestamp": "2022-11-09T15:45:00"
}
],
"subject": "Topic"
}
Какие изменения мне нужно внести, чтобы элементы в реальном списке соответствующим образом обновлялись и оставались на своих новых позициях после перемещения?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваш groupedFeatures — это не ссылка на vue, а вычисленное значение. Вы не можете обновить его с помощью обратного вызова из перетаскиваемого объекта.
Вместо того, чтобы вычислять его на основе значения переменной функций, я предлагаю просто вычислить его один раз в обратном вызове onMounted, где вы устанавливаете свои функции.
const groupedFeatures = ref([]);
onMounted(async() => {
const threadData = await fetchEmailThreads(route.params.id);
if (!threadData) return;
const featureMap = new Map();
features.value.forEach(f => {
if (!featureMap.has(f.type)) {
featureMap.set(f.type, {
type: f.type,
details: []
});
}
featureMap.get(f.type).details.push({
model_name: f.model_name,
value: f.value
});
});
groupedFeatures.value = Array.from(featureMap.values());
});
Это должно решить вашу проблему.