【问题标题】:Error in directive dragula update hook: "TypeError: Cannot read property 'drake' of undefined"指令 Dragula 更新挂钩中的错误:“TypeError:无法读取未定义的属性 'drake'”
【发布时间】:2021-03-13 03:01:17
【问题描述】:

我在项目中使用vue-dragula 来满足拖放列表的要求。

效果很好。但我在那个保持元素删除时间有以下错误。

指令 dragula 更新钩子中的错误:“TypeError:无法读取 未定义的属性“德雷克”

下面是我的代码示例

(模板 HTML 代码)

<ul v-dragula="dragDatas" bag="action-bag">
    <li v-for="(drDatas, drIndex) in dragDatas" :key="drDatas.id">{{drDatas.name}}</li>
</ul>

(脚本代码)

import 'vue-dragula/styles/dragula.css';

created () {
  Vue.vueDragula.options('action-bag', {
    invalid: function (el, handle) {
      return // CONDITION BASED
    }
  });
},

mounted () {
  const self = this;
  Vue.vueDragula.eventBus.$on('drop', async function ([bag, curElmt, allElmts]) {
    // drop event based functionalities
  })
}

【问题讨论】:

    标签: vue.js dragula


    【解决方案1】:

    我相信使用 vanilla Dragula 库而不是 Vue-Dragula 包装器会更容易。这将使您免于很多麻烦,还可以减小包大小。

    我是这样使用的:

    import dragula from 'dragula' 
    
    data()
    {
      return {
        stages: { // we have 5 lists - items can be dragged between any 2 of them
          LEAD_IN: [],
          HOMEOWNER_ADDED: [],
          PROPOSAL_GENERATED: [],
          WON: [],
          LOST: [],
        }, 
        drake: null,
      }
    },
    mounted()
    {
        // IMPORTANT !!! prevent default image dragging for IE which interferes badly with Dragula
        document.ondragstart = function () {
          return false
        }
        this.drake = dragula({
          isContainer: this.dragContainer,
          moves: this.dragMoves,
          accepts: this.dragAccept,
          mirrorContainer: document.getElementById('app'), //eslint-disable-line
        })
        this.drake.on('drop', this.drakeDrop)
        this.drake.on('drag', this.drakeStart)
        this.drake.on('over', this.drakeOver)
        this.drake.on('out', this.drakeStop)
        this.drake.on('cancel', this.drakeStop) 
    },
    methods:
    {
        dragContainer(el) {
          // defines containers for draggable items
          return 'kind' in el.dataset
        },
        dragMoves(el, source, handle, sibling) {
          // allows dragging only by using the HANDLE
          return 'move' in handle.dataset
        },
        dragAccept(el, target, source, sibling) {
          // only containers can accept draggable items
          return 'kind' in target.dataset
        },
        drakeStart(el, source) {
          // indicate which container's item we have started dragging
          source.classList.add('drag_src')
        },
        drakeOver(el, container, source) {
          source.classList.add('drag_src')
          container.classList.add('drag_dst')
        },
        drakeStop(el, container, source) {
          source.classList.remove('drag_src')
          container.classList.remove('drag_dst')
        },
        drakeDrop(el, target, source, sibling) {
          // EL was dropped into TARGET before SIBLING and originally came from SOURCE
          this.drake.cancel(true) // !!! very important - we do not want Dragula to mess with the DOM as it will confuse Vue
          if (source !== target) {
            // update arrays
            const task = this.stages[source.dataset.kind].splice(el.dataset.index, 1)[0]
            const dst = this.stages[target.dataset.kind]
            dst.splice(sibling ? sibling.dataset.index : dst.length, 0, task)
            this.updateTask(task, target.dataset.kind)
          }
        }, 
        updateTask(task, newStage) {
          this.loading = true
          this.$axios
            .post('/houses/stages', {
              lead_id: task.lead.id,
              kind: newStage,
            })
            .then(() => {
              this.loading = false
            })
            .catch((error) => {
              this.loading = false
              events.$emit(TOAST_ERROR, error.message || error)
            })
        }, 
    }
    

    每个列表的模板是

    <div :data-kind="kind" class="task_list">
      <div v-for="(task, idx) in list" :key="task.id" class="task_item" :data-index="idx">
        <div class="flexbox">
          <div class="content_move" data-move>this is the drag HANDLER</div>
          <button>some action, eventually</button>
        </div>
      </div>
    </div>
    

    kind 属性应该(在我的特定情况下)与 this.stages 对象的属性匹配。

    还有一些方便的样式

    .task_item {
      cursor: grabbing;
    }
    .task_list .task_item {
      cursor: default;
    }
    .task_list .task_item .content_move {
      cursor: move;
    }
    .task_list.drag_dst {
      border: 1px solid green;
    }
    .task_list.drag_src.drag_dst {
      border: 1px solid red;
    } 
    

    【讨论】:

      【解决方案2】:

      我通过隐藏和显示父组件解决了这个问题。

      【讨论】:

        猜你喜欢
        • 2020-08-14
        • 2021-07-14
        • 2021-04-12
        • 2021-12-22
        • 2019-12-20
        • 2020-09-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-28
        相关资源
        最近更新 更多