使用 vuedraggable 拖放后更新 Vuex

问题描述 投票:0回答:3

我创建了一个使用 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”对象,其中包含每个任务阶段的任务数组。拖放将任务卡从源移动到目标,但我已经找到了一种识别目标列表的方法。

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

谢谢

德斯

vue.js vuex vuetify.js vuedraggable
3个回答
1
投票

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

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

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


0
投票

我通过解析 move 事件的 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;


0
投票

我发现了可以绑定到可拖动元素的@change事件。当可拖动元素的内容(列表)更改并且它接受参数时,调用@change。由于我确实必须将元素克隆(或移动)到可拖动的位置,因此我在 onChange 方法上实现了该方法,该方法将列表的标识符和可拖动事件作为参数:

在我的代码中我实现了: const onChange = (列表, 事件) => { 如果(添加){

}//确保一个新元素已添加到列表中 }

© www.soinside.com 2019 - 2024. All rights reserved.