developit / htm

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.
Apache License 2.0
8.73k stars 170 forks source link

Slots are not rendered in Vue #217

Closed megaboich closed 3 years ago

megaboich commented 3 years ago

I am trying to render a slotted markup inside my Vue component, kind of following examples from here: https://v3.vuejs.org/guide/component-slots.html#slot-content

Unfortunately this seems not working or maybe I missing something?

My component:

import { html } from "../../dependencies.js";

export default {
  name: "Modal",
  props: {
    title: String,
    onclose: Function,
  },
  render() {
    return html`
      <div class="modal is-active">
        <div class="modal-background"></div>
        <div class="modal-card">
          <section class="modal-card-body">
            <slot></slot>
          </section>
        </div>
      </div>
    `;
  },
};

and I try to render it like this:

<${Modal}
    title="Export"
    onclose=${() => {
      this.isExportModalOpened = false;
    }}
  >
    <p>Hello, I am some slot content</p>
  <//>

Unfortunately it does not render "Hello..." inside my component, slot is rendered completely empty.

megaboich commented 3 years ago

A little experiment showed that if I change my component to standard Vue template engine it starts working correctly.

This works fine:


export default {
  name: "Modal",
  props: {
    title: String,
    onclose: Function,
  },

  template: `
      <div class="modal is-active">
        <div class="modal-background"></div>
        <div class="modal-card">
          <section class="modal-card-body">
            <slot>Content</slot>
          </section>
        </div>
      </div>
  `
};
developit commented 3 years ago

@megaboich Vue's JSX support does not allow using <slot>: https://v3.vuejs.org/guide/render-function.html#slots

Instead, you should use this.$slots:

import { html } from "../../dependencies.js";

export default {
  name: "Modal",
  props: {
    title: String,
    onclose: Function,
  },
  render() {
    return html`
      <div class="modal is-active">
        <div class="modal-background"></div>
        <div class="modal-card">
          <section class="modal-card-body">
+           <slot></slot>
+           ${this.$slots.default()}
          </section>
        </div>
      </div>
    `;
  },
};