antoni
antoni

Reputation: 5556

Is there a way to access Vue $scopedSlot's mounted DOM element?

I have a scoped slot named myElement, I can access it via this.$scopedSlots.myElement()[0].

Usually when a vnode is mounted there is a $el containing the DOM element, but not in scoped slots apparently, there is only an undefined elm.

I also tried to put a ref on the slot in the child template and access it through .context.$refs but it lists the refs on the parent template only.

Is there any way I can access that mounted DOM element, if its id or class is unknown from the child component?

Thanks


More Details:

Parent template (Pug)

child-component
  template(v-slot:myelement="{ on }")
    span My element content

Child component

  mounted () {
    console.log(this.$scopedSlots.myelement()[0])
    // From here I want to get the position of the span with
    // span.getBoundingClientRect()
  }

Reproduction link:

https://codepen.io/antoniandre/pen/BaogjrM?editable=true&editors=101

Upvotes: 3

Views: 3023

Answers (2)

antoni
antoni

Reputation: 5556

The only workaround that I've found so far is this:

First get the vnode of the scopedSlot, get its given context, crawl each vnode children of the context to find itself by the _uid key, which will contain the $el mounted element. This is not very straightforward but it does the trick.

mounted () {
    const { context } = this.$scopedSlots.activator()[0]
    console.log(context.$children.find(vnode => vnode._uid === this._uid).$el)
}

I asked in Vue forum and Vue chat but I am still looking for a better way, if there is let me know.

Upvotes: 2

Estradiaz
Estradiaz

Reputation: 3573

So something like this can be used to workaround:

mounted () {
    const myEl = this.$scopedSlots.myelement()[0];
    if(myEl.data && myEl.data.attrs && myEl.data.attrs.id){
      const id = myEl.data.attrs.id    
      console.log([this.$el.querySelector('#id')])
    } else {
      throw new Error('slot myelement needs an id'); 
    }
  }

or forcefully apply an id:

const Child = {

  render: function(h){
    const myEl = this.$scopedSlots.myelement()[0]
    myEl.data = {attrs: {id: 'id'}};
    console.log(myEl)
    return h('div', {}, [myEl])
  },

  mounted () {
      console.log([this.$el.querySelector('#id')])
  }
}

Upvotes: 1

Related Questions