Omar España
Omar España

Reputation: 125

Vue3 Render a component in a Custom Directive

I am trying to migrate a conditional rendering directive from Vue 2 to Vue 3. The directive changes the parent component from the "el" and adds a wrapper element that aggregates some logic.

In the Vue 2 version the process is simple as create a instance of the component, mount it, and adding the directive reciever as a child.

import EditableElement from '@/components/base/EditableElement'

Vue.directive('editable', {
  bind: function (el, binding, vnode) {
    let EE = Vue.extend(EditableElement)
    EE.$mount()
    vnode.elm = EE.$el
    vnode.elm.childNodes[0].appendChild(el)
})
}

But in Vue3 the $el atribute does not exist neither the mount() method, I been trying to create

a custom component using the h() function, but the result gives me a empty el, and when I try to change the vnode it does not work. How can i do this?

 app.directive('tooltip', {
  beforeMount(el, binding, vnode) {
    let new_el = h('div', { class: 'tooltip'}, [
      h('div', { class: 'tooltip__icon' }),
      h(vnode)
      'message'
    ])
    vnode = new_el

  }
})

Upvotes: 8

Views: 2233

Answers (1)

TheAlexLichter
TheAlexLichter

Reputation: 7289

Using createApp to mount the element as new Vue app seems to work 🙈

const app = createApp(App)
app.directive('tooltip', {
  mounted (el: HTMLElement, _, vnode) {
    let newElement = h('div', { class: 'tooltip' }, [
      h('div', { class: 'tooltip__icon' }),
      h(vnode),
      'message'
    ])
    createApp(newElement).mount(el)
  }
})

Upvotes: 1

Related Questions