'render a Vue slot in a layout from component

I'm having problems with a named slot. This seems like it should work. In the code below I'm trying to use a named slot "sidebar". I would expect my sidebar slot content to show up between the Sidebar starts and Sidebar ends text but nothing shows up in that slot. Everything renders in the main slot.

Here's my code.

route...

{
  path: "/test",
  name: "test",
  meta: {
    layout: "test-layout"
  },
  component: () =>
    import("@/pages/Test.vue")
},

and App.vue template...

<template>
  <div id="app">
    <component  :is="layout">
      <router-view />
    </component>
  </div>
</template>

and test-layout...

<template>
  <div>
    <div>
      <h1>Sidebar starts</h1>
      <slot name="sidebar"/>
      <h1>Sidebar ends</h1>
    </div>
    <div class="container">
      <h1>Content starts</h1>
      <slot/>
      <h1>Content ends</h1>
    </div>
  </div>
</template>

and page Test.vue...

<template>
  <test-layout>
    <span slot="sidebar">sidebar slot content {{forecast.todaySummary}}</span>
    <div>main slot content {{forecast.currentSummary}}</div>
  </test-layout>
</template>

<script>
import api from "@/js/web-services";
export default {
  data() {
    return {
      forecast: null
    };
  },
  created() {
    api.getDailyForecast().then(response => {
      this.forecast = response.data;
    });
  }
};
</script>

and the import in my main.js

import TestLayout from "./layouts/test-layout.vue";
Vue.component('test-layout', TestLayout);

Why isn't my sidebar slot working?

UPDATE

If I get rid of the two lines in main.js and add

import TestLayout from "@/layouts/test-layout.vue";

and

export default {
  components: { TestLayout },

  data() {...

to Test.vue then it works.



Solution 1:[1]

In your router file you are using layout: "test-layout" this means what ever comes in your vue component will be rendered in base test-layout.

There are two ways as far as I know to render the layouts.

  1. Do not define layout in router file and on parent component define named slots like this<slot #header></slot><slot #body></slot> then every slot will be rendered within this (test-layout) layout, and then in your each component extend like this <test-layout><template header>Header content</template><template body>Body content</template></test-layout>.
  2. Defining layout in router file like you did, you can not further use in slots in that layout, you can just import other components e.g <template><Component1><Component2> </template>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Usman Ali Aslam