-1

我创建了一个使用 Vuetify、Vuex 和 vuedraggable 的 Vue 应用程序。通过拖放包含相关信息的 v-card 组件按预期运行,但我无法找到识别目的地的方法,以便我可以更新 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”对象,其中包含每个任务阶段的任务数组。拖放将任务卡从源移动到目标,但我已经能够找到一种方法来识别目标列表。

请提供有关如何确定在移动后应该更新“buckets”对象中的哪些列表的建议。

谢谢

德斯

4

2 回答 2

1

如果您查看文档,您会看到 vuedraggable 有一个 @end 事件,该事件将在移动元素后触发。记录该事件时,您会注意到很多有用的信息 - 例如 oldIndex、newIndex 等等。

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

来源:https ://github.com/SortableJS/Vue.Draggable#events

于 2020-04-01T07:51:20.057 回答
0

我能够通过解析移动事件的 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;

于 2020-04-02T06:01:44.620 回答