Перетаскиваемые элементы Vue возвращаются в исходное положение после перетаскивания

Я использую 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"
}

Какие изменения мне нужно внести, чтобы элементы в реальном списке соответствующим образом обновлялись и оставались на своих новых позициях после перемещения?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш 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());
});

Это должно решить вашу проблему.

Другие вопросы по теме