Обновление Vuex после перетаскивания с помощью vuedraggable - PullRequest
0 голосов
/ 31 марта 2020

Я создал Vue приложение, которое использует Vuetify, Vuex и vuedraggable. Компонент функционирует, как и ожидалось, с помощью перетаскивания v-карты, содержащей связанную информацию, но я не смог найти способ определить место назначения, чтобы я мог обновить Vuex Store

<template>
  <v-container>
    <v-row justify='center'>
      <v-col v-for="stage in stages" :key="stage.value">
        <span class="card-text-bold">{{ stage.heading }}</span>
        <draggable :list="buckets[stage.name]" group="openTasks" :move="handleStatus">
          <v-card color="commentCard" class="list-group mt-3" v-for="task in buckets[stage.name]" :key="task._id">
            <v-card-text>

              <span class="card-text-bold">{{ task.title}}</span>
            </v-card-text>

            <v-card-text>
              <span class="card-text"> {{ task.description}} </span>
            </v-card-text>

            <v-card-text>
              {{ task.assignee}}<v-icon right @click="goToTask(task._id)">edit</v-icon>
            </v-card-text>

          </v-card>
        </draggable>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import { mapGetters } from 'vuex';
import draggable from 'vuedraggable';
import moment from 'moment';

export default {
  name: 'Tasks',

  components: {
    draggable
  },

  data() {
    return {
      stages: [
        { heading: 'Created', name: 'created' },
        { heading: 'Assigned', name: 'assigned' },
        { heading: 'In Progress', name: 'in progress' },
        { heading: 'On Hold', name: 'on hold' },
        { heading: 'Complete', name: 'complete' },
        { heading: 'Closed', name: 'closed' }
      ]
    };
  },

  created() {
    this.handleGetTasks();
  },

  computed: {
    ...mapGetters(['user', 'loading', 'tasks', 'buckets'])
  },

  methods: {
    getTimeFromNow(time) {
      return moment(new Date(time)).fromNow();
    },
    goToTask(taskId) {
      this.$router.push(`/task/${taskId}`);
    },

    handleGetTasks() {
      const userRole = localStorage.getItem('role');
      const fullname = localStorage.getItem('fullname');

      switch (userRole) {
        case 'Manager': {
          this.$store.dispatch('getAllTasks');
          break;
        }

        case 'Requester': {
          this.$store.dispatch('getRequestTasks', {
            fullname: fullname
          });
          break;
        }

        case 'Assignee': {
          this.$store.dispatch('getAssignTasks', {
            fullname: fullname
          });

          break;
        }
      }
    },

    stateTasks(target) {
      console.log('state', target);
      if (this.buckets[target] > 0) return this.buckets[target];
      else return [];
    },

    handleStatus(evt) {
      const movedId = evt.draggedContext.element._id;
      var targetStage;

      console.log('source', movedId, 'target', Object.keys(evt.relatedContext.list));
    }
  }
};
</script>

Источник список данных, используемых здесь, является объектом 'buckets', который содержит массив задач для каждого из этапов задачи. Перетаскивание перемещает карты задач из источника в цель, но я смог найти способ идентифицировать список целей.

Пожалуйста, дайте совет, как я могу определить, какой из списков в «корзинах» 'объект должен быть обновлен после перемещения.

Спасибо

Des

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Если вы посмотрите на документацию, вы увидите, что vuedraggable имеет событие @end, которое сработает после перемещения элемента. При регистрации этого события вы заметите довольно много полезной информации, такой как oldIndex, newIndex и др ..

<draggable :list="list" @end="onEnd">

Источник: https://github.com/SortableJS/Vue.Draggable#events

0 голосов
/ 02 апреля 2020

Я смог решить эту проблему, проанализировав элемент HTML события перемещения.

Заголовок для каждого из столбцов этапа можно затем использовать в качестве идентификатора целевого списка.

Вот код

<template>
  <v-container>
    <v-row justify='center'>
      <v-col v-for="(stage, index) in stages" :key='index'>

        <draggable :list="buckets[stage]" group="openTasks" :move='handleMove'>
          <span slot="header" :tag="stage" class="card-text-bold">{{ stage }}</span>
          <v-card color="commentCard" class="list-group mt-3" v-for="task in buckets[stage]" :key="task._id">
            <v-card-text>

              <span class="card-text-bold">{{ task.title}}</span>
            </v-card-text>

            <v-card-text>
              <span class="card-text"> {{ task.description}} </span>
            </v-card-text>

            <v-card-text>
              {{ task.assignee}}<v-icon right @click="goToTask(task._id)">edit</v-icon>
            </v-card-text>

          </v-card>
        </draggable>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import { mapGetters } from 'vuex';
import draggable from 'vuedraggable';
import moment from 'moment';

export default {
  name: 'Tasks',

  components: {
    draggable
  },

  data() {
    return {
      stages: ['created', 'assigned', 'in progress', 'on hold', 'complete', 'archive']
    };
  },

  created() {
    this.handleGetTasks();
  },

  computed: {
    ...mapGetters(['user', 'loading', 'tasks', 'buckets'])
  },

  methods: {
    getTimeFromNow(time) {
      return moment(new Date(time)).fromNow();
    },
    goToTask(taskId) {
      this.$router.push(`/task/${taskId}`);
    },

    handleGetTasks() {
      const userRole = localStorage.getItem('role');
      const fullname = localStorage.getItem('fullname');

      switch (userRole) {
        case 'Manager': {
          this.$store.dispatch('getAllTasks');
          break;
        }

        case 'Requester': {
          this.$store.dispatch('getRequestTasks', {
            fullname: fullname
          });
          break;
        }

        case 'Assignee': {
          this.$store.dispatch('getAssignTasks', {
            fullname: fullname
          });

          break;
        }
      }
    },

    handleMove(evt) {
      const movedId = evt.draggedContext.element._id;
      var stageTag = evt.relatedContext.component.rootContainer.firstElementChild.innerText;
      if (this.stages.includes(stageTag)) {
        this.$store.dispatch('changeStatus', {
          taskId: movedId,
          status: stageTag
        });
      }
    }
  }
};

Расшифровка компонента HTML выполняется с помощью этого

evt.relatedContext.component.rootContainer.firstElementChild.innerText;

...