karol-f / vue-custom-element

Vue Custom Element - Web Components' Custom Elements for Vue.js
https://karol-f.github.io/vue-custom-element/
MIT License
1.97k stars 187 forks source link

Events within component slots #257

Closed rglodzinski closed 3 years ago

rglodzinski commented 3 years ago

I have two components: "my-btn" and "my-item".

my-btn

<template>
  <button class="br-btn" v-on="$listeners" v-bind="$attrs">
    <slot>{{ label }}</slot>
  </button>
</template>

<script>
export default {
  name: "MyBtn",
  props: ["label"]
};
</script>

my-item

<template>
  <div class="item">
    <slot />
  </div>
</template>

<script>
export default {
  name: "MyItem"
};
</script>

Build using this script defined in my package.json: "build:wc-custom-element": "vue-cli-service build --target lib --inline-vue --name dsgov src/main-custom-element.js".

So I use the components in a React application.

I purposely defined in "my-btn", v-on="$listeners", to allow the component's internal button events to be passed to the web component.

I can capture "my-btn" events perfectly, with one exception: when "my-btn" is rendered as a child of "my-item".

This works

import React from "react";

const TodoList = () => {
  const handleClick = () => {
    alert("Button clicked");
  };

  return (
    <div>
      <my-btn onClick={handleClick}>Click me</my-btn>
    </div>
  );
};

export default TodoList;

This doesn't work

import React from "react";

const TodoList = () => {
  const handleClick = () => {
    alert("Button clicked");
  };

  return (
    <my-item>
      <my-btn onClick={handleClick}>Click me</my-btn>
    </my-item>
  );
};

export default TodoList;

Tks

karol-f commented 3 years ago

Hi, there's something with the formatting - I can't see your code. Anyway - each component, nested in slot, is separate Vue instance and won't communicate with other vue custom element (unless you will use props or some shared event bus or store).

rglodzinski commented 3 years ago

Hi, there's something with the formatting - I can't see your code. Anyway - each component, nested in slot, is separate Vue instance and won't communicate with other vue custom element (unless you will use props or some shared event bus or store).

Fix the formatting.

karol-f commented 3 years ago

Hi, conclusion is the same - my-btn won't pass events to my-item - these are separated Vue instances.

rglodzinski commented 3 years ago

Hi, conclusion is the same - my-btn won't pass events to my-item - these are separated Vue instances.

Okay, thanks for the quick reply. Can you indicate where to see an example of how to implement the solution via props or with a shared event bus? Tks

karol-f commented 3 years ago

You can import js file with sth like this - https://blog.logrocket.com/using-event-bus-in-vue-js-to-pass-data-between-components/

Regards