指令 Dragula 更新挂钩中的错误:“TypeError:无法读取未定义的属性 'drake'”

Posted

技术标签:

【中文标题】指令 Dragula 更新挂钩中的错误:“TypeError:无法读取未定义的属性 \'drake\'”【英文标题】: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
  )

【问题讨论】:

【参考方案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】:

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

【讨论】:

以上是关于指令 Dragula 更新挂钩中的错误:“TypeError:无法读取未定义的属性 'drake'”的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 客户端 useMutation 挂钩中的 refetchQueries 问题

Mongoose 更新中间件 - 需要为每个更新中间件创建挂钩?

第二次使用 ng2-dragula 进入页面时出错

Angular 2:如何有条件地应用属性指令?

无法使用反应挂钩更新地图中的折线

无法读取上下文提供程序中的 useReducer 挂钩更新的状态