4

In vue2 I could use this.$el

export default { 
render() {
return this.$slots.default[0]
},
mounted() {
Sortable.create(this.$el, {});
})
}

If, in vue3 I try to use this.$slots.default()[0] I can't see how to target the element. If I use a template ref, I can get the div, but not the contained slot.

The closest question / answer I have found is here Vue 3 Composition API - How to get the component element ($el) on which component is mounted

but this also seems to give the div, but not the slot $el.

This was extremely powerful in vue2 because sortable could be passed a ul, or a div, or another constructed sortable vue component in a slot, and work without the element having to be defined in the child component and I can't work out how to replicate this in vue3.

I originally came across this in a screen cast by Adam Wathan: "Building a Sortable Component with Vue.js", but this was vue2.

Simon M
  • 41
  • 3

1 Answers1

0

I've come up with the following (perhaps there are better out there)

Use template ref:

<template>
    <div ref="root">
        <slot></slot>
    </div>
</template>

Then in the script:

import { ref, onMounted } from 'vue'
export default {
   setup() {
      const root = ref(null)

      onMounted(() => {
        // the DOM element will be assigned to the ref after initial render
        // console.log(root.value.children[0]) // this is your $el
        let el = root.value.children[0]
        Sortable.create(el, {})
      })

      return {
        root
      }
   }
}
Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
Simon M
  • 41
  • 3