【问题标题】:Updating Vuex following Drag and Drop using vuedraggable使用 vuedraggable 在拖放后更新 Vuex
【发布时间】:2020-07-12 12:15:44
【问题描述】:

我创建了一个使用 Vuetify、Vuex 和 vuedraggable 的 Vue 应用程序。通过拖放包含相关信息的 v-card 组件按预期运行,但我无法找到识别目的地的方法,以便我可以更新 Vuex 商店

<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”对象中的哪些列表应在移动后更新的建议。

谢谢

【问题讨论】:

  • 在这种情况下,如果您创建一个 codepen/jsbin/etc 工作示例,那么获得帮助会更容易......
  • 这不是一个可以在 codepen 中轻松重现的“编码”问题。它主要与 vuedraggable 包有关,因此只能由具有实现类似应用程序经验的人来回答。

标签: vue.js vuex vuetify.js vuedraggable


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • @end 确实返回了很多信息,但我找不到任何可以识别目标列表的信息。我的应用程序为每个项目阶段使用一个列表,以便可以在列表之间移动任务。我能够找到目标的唯一方法是遍历每个列表中的任务以找到与列表不匹配的任务。这解决了问题,但它似乎是一个蛮力解决方案。我正在寻找一些方法来从拖动事件中识别目标列表
    • 如果你能提供一个代码框,那就太好了,这样我们就可以在同一个页面上了解你的应用程序的行为方式。我觉得我明白了你想要做的事情的要点,但我真的很想尝试一两件事,因此我之前的回答有点笼统。我不记得@end 返回的所有属性,但我很确定有一个目标元素。您可能会在标记中提供某种标识符属性,以便您可以轻松识别项目,而无需再次遍历所有项目。不确定这在您的场景中是否可行。再次,请提供一个代码框
    • 我确实尝试过向每个 v-col 添加一个类然后搜索元素的想法,但我没有足够的经验在元素中找到该标识符。我以前没有创建过沙箱或 codepen,所以我应该学习如何做到这一点
    • 它基本上是您的编辑器,但在浏览器中:) 超级方便。试一试。它真的不像看起来那么吓人
    猜你喜欢
    • 2019-05-23
    • 2021-04-21
    • 2021-08-14
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多