Now I want the content inside the modal to be d" /> Now I want the content inside the modal to be d" /> Now I want the content inside the modal to be d"/>

Injecting html - using slot or v-html?

5.7k Views Asked by At

So here’s my case:

I’m creating a modal via:

<Modal id="modal">    
    <my-component></my-component>    
</Modal>

Now I want the content inside the modal to be dynamic, so I can put <input> or <table> or w/e. I’ve tried using slots (it works), but it isn’t really dynamic. I’m wondering if I missed something that would allow the slot to be a bit more dynamic.

Here’s how my modal is set up:

<div 
    :id="id"
    class="main" 
    ref="main" 
    @click="close_modal"
>
    <div ref="content" class="content" :style="{minHeight: height, minWidth: width}">
        <div ref="title" class="title" v-if="title">
            {{ title }}
            <hr/>
        </div>
        <div ref="body" class="body">
            <slot></slot>
        </div>
    </div>
</div>
1

There are 1 best solutions below

4
AudioBubble On

I think using slots is a good choice for this. With the introduction of slot-scope in 2.5, you basically get a reverse property capability where you can set defaults within the child component and access them within the parent. They are of course completely optional to use and you're free to place whatever content you like in the slots.

Here's an example component that would allow you to customize the header, body and footers as you see fit:

// MyModal.vue
<template>
  <my-modal>
    <slot name="header" :text="headerText"></slot>
    <slot name="body" :text="bodyText"></slot>
    <slot name="footer" :text="footerText"></slot>
  </my-modal>
</template>

<script>
  export default {
    data() {
      return {
        headerText: "This is the header",
        bodyText: "This is the body.",
        footerText: "This is the Footer."
      }
    }
  }
</script>

// SomeComponent.vue
<template>
  <div>
    <my-modal>
      <h1 slot="header" slot-scope="headerSlotScope">
        <p>{{ headerSlotScope.text }}</p>
      </h1>
      <div slot="body" slot-scope="bodySlotScope">
        <p>{{ bodySlotScope.text }}</p>
        <!-- Add a form -->
        <form>
          ...
        </form>
        <!-- or a table -->
        <table>
          ...
        </table>
        <!-- or an image -->
        <img src="..." />
      </div>
      <div slot="footer" slot-scope="footerSlotScope">
        <p>{{ footerSlotScope.text }}</p>
        <button>Cancel</button>
        <button>OK</button>
      </div>
    </my-modal>
  </div>
</template>

<script>
import MyModal from './MyModal.vue';

export default {
  components: {
    MyModal
  }
}
</script>