6

I am creating a web-component using VueJS 3, I want to expose a method on the component allowing the user to do something like this:

  <custom-component id="x1" />

  <script>
    var component = document.getElementById("x1");
    
    component.customMethod(); // as focus() method on native elements
  </script>

If I define a method on the component, I can call the method inside the component. But the method is not available when I use it as a web-component.

  //main.ts/js
  import { defineCustomElement } from "vue"
  import component from "./component.ce.vue"

  const element = defineCustomElement(component );

  customElements.define("custom-component ", element);
  //component.ce.vue
  const customMethod = () => { console.log("Executed"); }

How I can indicate to Vue Component Wrapper that the customMethod will be available outside the component?

1 Answer 1

10

In <script setup>, use the defineExpose() macro:

<script setup>
const customMethod = () => {⋯}
      👇
defineExpose({ customMethod })
</script>

In the setup() hook, use the expose property of the context argument:

<script>
export default {   👇
  setup(props, { expose }) {
    const customMethod = () => {⋯}
      👇
    expose({ customMethod })
  }
}
</script>

In the Options API, use the expose option:

<script>
export default {
     👇
  expose: ['customMethod'],
  methods: {
    customMethod() {⋯}
  }
}
</script>

Currently (as of Vue 3.2.31), the only way to access the custom element's exposed properties is through its _instance.exposed property:

<!-- example/index.html -->
<body>
  <custom-component id="x1"></custom-component>
  <script>
    const el = document.getElementById('x1')
                   👇
    el._instance.exposed.customMethod()
  </script>
</body>

Since _instance is a private property, use this solution with caution, as the property could be renamed/removed in a future release.

demo (<script setup>)

demo (setup() hook)

demo (Options API)

Sign up to request clarification or add additional context in comments.

1 Comment

As of 3.3.7, accessing _instance in a component defined with a .ce.vue file that has defineExpose({ .. }) doesn't work and the methods are not available for calling. -1 for this answer. There is a bug report considered to be a feature request, which is a clear regression from 2.x (github.com/vuejs/core/issues/5540) that is over a year old and nobody is looking into solving the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.