Subscribe on changes!

Methods exposed with defineExpose are not available on custom element

avatar
Mar 7th 2022

Version

3.2.31

Reproduction link

stackblitz.com

Steps to reproduce

Open repro and you should see 'hello' in the console instead of Uncaught TypeError: ce.value.hello is not a function

What is expected?

Methods exposed with defineExpose are available on given component instance

What is actually happening?

They are not exposed

avatar
Mar 7th 2022

Is there anything in the docs for defineCusromElement giving you the impression that they should be?

I don't think we planned for that, it's simply not supported. We don't expose anything about the component on the custom element wrapper except its props.

avatar
Mar 10th 2022

I was just following this documentation and assumed that if defineExpose default behavior is not documented there us not supported (like slots) it means that this is a bug. Which also makes sense when properties are exposed.

Either way if it's like a triage issue how can we turn this into feature?

avatar
Apr 24th 2022

I think it's useful for expose to allow certain things to be exposed, such as' input.click() ', which I currently handle with object.defineProperty

avatar
May 5th 2022

I too have this problem but I got to say that it's not consistent. Some components work and other don't. I can't put a finger on a reason why. They all use defineExpose normally.

It seems to affect components that are conditionally rendered via a v-if but the stackblitz example does not do this, so I have no clue why this is happening.

avatar
May 18th 2022

Why is his marked as as feature request? This is most definitely a bug. Right now we work around it by defining a useless property and listen to it in order to trigger the method that does not get exposed.

I stand corrected. See below.

avatar
May 18th 2022

@m-ghaoui even though I created this issue I can see how this is simply a new feature :)

for time being I use this composable to get to the host:

import { getCurrentInstance, ref, onMounted } from 'vue'

export function useHost() {
  const host = ref(null)
  onMounted(() => {
    host.value = getCurrentInstance()?.proxy?.$el?.parentNode?.host
  })
  return host
}

and inside your custom element you can expose your method with simple assignment:

function foo () { … }
host.value.foo = foo
avatar
May 18th 2022

Oh I get it now. defineExpose() only exposes properties. Exposing a method is a new feature.

Okay 🙂 I stand corrected.

avatar
Jul 12th 2022

I created a PR @LinusBorg #6256

avatar
Jan 12th 2023

I too have this problem but I got to say that it's not consistent. Some components work and other don't. I can't put a finger on a reason why. They all use defineExpose normally.

It seems to affect components that are conditionally rendered via a v-if but the stackblitz example does not do this, so I have no clue why this is happening.

I confirm, it's been bugging me that why it works on one Component and not another.

avatar
Apr 21st 2023

Are there any plans on adding this new feature? The PR from @LinusBorg is getting pretty old.

avatar
May 10th 2023

facing the same issue, temporary workaround to access the exposed method via $.exposed, e.g.

const myRef = ref()
// <myElement ref="myRef"></myElement>

myRef.value.$.exposed.ExposedMethod()
avatar
Nov 30th 2023

Any progress on that over-a-year-old shortcoming of Vue's implementation of webcomponents? Is that ever going to land in Vue or should we just create and use a fork to get it implemented?