1
votes

I have an external div that I need to render inside my Vue app. I'm trying to use a slot, like but that's a no go as nothing renders.

Any ideas?

Goal is to have HTML like this (Vue mounts on #app):

<div id="app" data-slot-header="#header"></div>

<div id="header">
  <h1>Title here</h1>
</div>

Then the Vue component

<template>
  <div>
    <slot name="header"></slot>
  </div>
</template>
2

2 Answers

2
votes

You can use a dynamic <component> and refer to your #header element as a template reference.

For example

new Vue({
  data: () => ({
    headerComponent: {
      template: '#header' // refer to template element by selector
    }
  }),
}).$mount('#app')
#app:before,#header:before{position:absolute;top:0;right:0;color:rgba(1,1,1,.5);font-size:.8rem}#app{border:1px solid #666;position:relative}#app:before{content:'Vue app'}#header{position:relative;opacity:.5}#header:before{content:'Original header'}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
  <p>Dynamic component rendered here 👇</p>
  <component :is="headerComponent"></component>
</div>

<div id="header">
  <h1>Title here</h1>
</div>
0
votes

Slots are mainly used with reusable Vue components so that the parent component can render custom stuff inside designated sections of the child. The root component does not have a parent, so it doesn't make sense to use slots for this.

Why can't you just hard-code the div in the template? Or do you need it to be dynamic; will you be swapping out the header contents in some situations? Please provide more information about what your use-case is, otherwise my answer is "just hard-code it".

Take a look at portal-vue. It allows child components to render templates anywhere in the DOM. This might work for your situation.