2

I have a BaseModal Component like this :

<template>
    <div class="base-modal" :class="{open: isOpen}">
        <div class="modal">
            <h2 class="modal-title">
                <slot name="title"></slot>
            </h2>
            <div class="modal-content">
                <slot name="content"></slot>
            </div>
        </div>
    </div>
</template>


<script lang="ts">
    import { Vue, Component } from "vue-property-decorator";

    @Component({})
    export default class BaseModal extends Vue {

        public isOpen: boolean = false;

        // Some methods

    }
</script>

I want to create an other modal component that will extend this one and pass it the content for the named slots. Here is where I am :

<template>
    // How to give slots content here
</template>


<script lang="ts">
    import BaseModal from "@app/components/BaseModal.vue";
    import { Vue, Prop, Component } from "vue-property-decorator";

    @Component({
        extends: BaseModal,
    })
    export default class OtherDropdown extends Vue {
    }
</script>

The extends is working but I can't figure out how to pass content to the named slot of the extended component. Not to have to write again all the BaseModal template.

Thanks

I'm using VueJS 2.6.8

Mushr00m
  • 2,258
  • 1
  • 21
  • 30

1 Answers1

1

You would want to use components named slots like this:

<template>
  <BaseModal>
    <template v-slot:title>
      Some Title
    </template>
    
    <template v-slot:content>
      Some content goes here
    </template>
  </BaseModal>
</template>

You can read more about named slots here: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots

Hope this helps!

tony19
  • 125,647
  • 18
  • 229
  • 307
Derek Pollard
  • 6,953
  • 6
  • 39
  • 59
  • 2
    This is already what I'm doing in the code of the example. Here you don't extend the component you just use it in an other component. – Mushr00m Mar 28 '19 at 14:34
  • @Mushr00m - I don't believe `@extends`, in this instance is proper to use. You're effectively overwriting the parent template with your child component by using extends. I believe the proper way of doing this is HOC and slots, as shown – Derek Pollard Mar 28 '19 at 14:57
  • Thanks for the answer. My issue with this technique is that my component `Foo` using `OtherDropdown` that uses `BaseModal` cannot call `open()` method. Because the `BaseModal` is nested inside the `OtherDropdown` component. So the parent doesn't have access to methods even using `$refs`. How would you to to make `OtherDropdown` having access to all `BaseModal` methods without rewritting them ? – Mushr00m Mar 31 '19 at 22:22
  • Have You figured it out already? Using `$refs` should work I believe as described here: https://stackoverflow.com/a/47565763/1505369 . I believe it could also be possible to pass the whole `this` element with `v-model`, which means emitting some event after initialization, but it seems like a quite a dirty solution to me. – kcpr Sep 23 '19 at 07:51