Abenezer Mario
Abenezer Mario

Reputation: 75

draggable element must have an item slot

I was trying to use vuedraggable into my Notebook application and i get this error when i add the draggable component. Here is the code and the error. I would appreciate the help.

Here is the error message i am getting.

Error: draggable element must have an item slot at computeNodes (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:4483:11) at computeComponentStructure (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:4525:15) at Proxy.render (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:4644:32) at renderComponentRoot (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:965:44) at componentEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4382:53) at reactiveEffect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:71:24) at effect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:46:9) at setupRenderEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4365:89) at mountComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4324:9) at processComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4284:17)

I am not using the vuedraggable component on my app.vue instead am passing it as a component from my todo.vue file.

Any help would be great. Thank you

Upvotes: 5

Views: 20522

Answers (2)

H3lltronik
H3lltronik

Reputation: 886

Just surround your item in a <template #item> tag, the error is saying to you that inside a draggeable component must always be a slot called item.

In Vue 3 you assign a template to a slot by using #{slotName}

Check this demo from the docs

example:

<draggable
      :list="list"
      :disabled="!enabled"
      item-key="name"
      class="list-group"
      ghost-class="ghost"
      :move="checkMove"
      @start="dragging = true"
      @end="dragging = false"
    >
      <template #item="{ element }">
        <div class="list-group-item" :class="{ 'not-draggable': !enabled }">
          {{ element.name }}
        </div>
      </template>
</draggable>

Upvotes: 19

Maka
Maka

Reputation: 663

If you are using Vue3 and/or you have nested component then you can implement it as following.

App.vue

<draggable v-model="bookmarks" ghost-class="ghost" group="people" @start="drag=true" @end="dragEnded" :move="checkMove" item-key="id">
  <template #item="{element}">
    <bookmark-card :bookmark="element">
    </bookmark-card>
  </template>
</draggable>

The key part is adding <bookmark-card :bookmark="element"> as :bookmark cast into component.

Then it can be used inside of component as:

BookmarkCard.vue

<template>
  <li class="p-2 mb-3 m-1.5 flex items-center bg-gray-900 shadow rounded-lg single-bookmark hover:bg-green-500">
      <div class="items-center">
          <button @click="editBookmark" type="button" class="bookmark-edit h-6 w-6 text-white bg-green-700 dark:hover:bg-green-800 font-medium rounded-lg text-sm text-center dark:bg-green-600 dark:hover:bg-gray-600">
            <svg class="w-4 h-4 dark:text-white m-2" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
              <path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"></path>
              <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
            </svg>
          </button>
          <span class="absolute text-white font-small text-sm">{{ bookmark.bookmark_name}}</span>
        </div>
    </li>
</template>
<script>
import Avatar from "vue3-avatar";
export default {
  components: {
    Avatar,
  },
  props: {
    bookmark: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    editBookmark() {
      //  To exit draggable component and reach App.vue parent method, add $parent.$parent twice
      this.$parent.$parent.editBookmarkParent(this.bookmark);
    },
  }
}
</script>

Upvotes: 1

Related Questions