In defineCustomElement does not send event's params
Vue version
3.2.37
Link to minimal reproduction
https://codesandbox.io/s/vue-custom-element-prueba-concepto-c6b846
Steps to reproduce
Issue
I have been doing a solution to implement Web components with Vue. This solution needs to use plugins, so I had to implement the defineCustomElement by overwriting the setup. When this procedure is done, the emit does not send parameters. It is also not recognizing custom events; it is only recognizing native events like click. So, in short, I need to send parameters through the emit and overwriting the setup of the defineCustomElement (to be able to inject plugins like the router).
What is expected?
I am waiting to receive the parameters sent through the event and the custom event
What is actually happening?
does not recognize the custom event or the event parameters
System Info
System:
OS: Linux 5.15 Manjaro Linux
CPU: (8) x64 AMD Ryzen 7 3700U with Radeon Vega Mobile Gfx
Memory: 11.43 GB / 17.52 GB
Container: Yes
Shell: 5.9 - /usr/bin/zsh
Binaries:
Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
Yarn: 1.22.19 - /usr/bin/yarn
npm: 8.18.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
npmPackages:
vue: ^3.2.37 => 3.2.37
Any additional comments?
It is webComponent.
well, you are mounting a child component in your custom element, but don't re-remit its events.
If this was a normal vue app, would you expect the child's event to be available in the component above the component that mounted the child just like that? No - you would need to re-emit the event.
In its most minimal form, this could look like this:
h(component, {
...props,
onDemo: (...args) => emit("demo", ...args)
});
Its up to you to figure out a way to config this dynamically for each of your wrapped custom elements, i.e. by reading the child's emits
option.
Thank you very much for your help. @LinusBorg Unfortunately what you said makes a lot of sense, but I implemented it and it still doesn't work. You can look at the code and verify that it still doesn't work.
import {
defineCustomElement as VueDefineCustomElement,
h,
createApp,
getCurrentInstance
} from "vue";
export const defineCustomElement = (component, { plugins = [] } = {}) =>
VueDefineCustomElement({
...component,
setup(props) {
const app = createApp(component);
// install plugins
plugins.forEach(app.use);
const inst = getCurrentInstance();
Object.assign(inst.appContext, app._context);
Object.assign(inst.appContext, app._context.provides);
return () =>
h(component, {
...props,
ondemo: (...args) => inst.emit("demo", ...args),
click: (...args) => inst.emit("click", ...args)
});
}
});
What I think is that you have to forward the events, as you say, but I don't know if this is done by prototyping or if I am missing something in the h function.
I add that this code is to make a Webcomponent, that is to say, it will be used in any framework or natively; not necessarily in a Vue project.
https://codesandbox.io/s/vue-custom-element-prueba-concepto-c6b846?file=/src/utils.js:0-794
- setup(props) {
+ setup(props, { emit }) {
// ....
- ondemo: (...args) => inst.emit("demo", ...args),
+ onDemo: (...args) => emit("demo", ...args),
you have a misspelled prop, and also don't need to use getCurrentInstance()