Using slots



  • I would like to add new slots but it’s not working, for instance I have a public component which has 2 child components.

    router.js

    routes: 
    { path:
          '/public', component: load('Public'),
          children: [
            { path: 'login', component: load('Login') },
            { path: 'register', component: load('Register') }
          ]
        }
    ...
    

    And my Public.vue component is like

    <template>
      <q-layout>
        <!-- Header -->
        <div slot="header" class="toolbar">
          <!-- opens left-side drawer using its ref -->
          <button class="hide-on-drawer-visible" @click="$refs.leftDrawer.open()">
            <i>menu</i>
          </button>
          <q-toolbar-title :padding="1">
            <slot name="title"></slot>
          </q-toolbar-title>
        </div>
        <!-- Left side Drawer -->
        <q-drawer ref="leftDrawer">
          <div class="toolbar light">
            <div class="toolbar-content">
              <div class="toolbar-title padding-1">
                {{ 'Menu' | translate }}
              </div>
            </div>
          </div>
    
          <div class="list platform-delimiter">
            <q-drawer-link to="/public/login">{{ 'Login' | translate }}</q-drawer-link>
            <q-drawer-link to="/public/register">{{ 'Register' | translate }}</q-drawer-link>
          </div>
        </q-drawer>
    
        <router-view class="layout-view layout-padding">
        </router-view>
    
      </q-layout>
    </template>
    

    As you can see I have added a <slot name="title"></slot> but when I call the slot from a child component the title is not renderd in the slot, for example if I call from my Login.vue component

    <template>
      <div>
        <div slot="title">{{ 'Login' | translate }}</div>
        <form>
          <div class="floating-label">
            <input type="text" class="full-width" v-model="email" required/>
            <label>{{ 'Email' | translate }}</label>
          </div>
          <div class="floating-label">
            <input type="text" class="full-width" v-model="password" required/>
            <label>{{ 'Password' | translate }}</label>
          </div>
    
          <div>
            <button type="submit" class="primary full-width">{{ 'Login' | translate }}</button>
          </div>
        </form>
      </div>
    </template>
    

    The title is not rendered in the <slot name="title"></slot>, How should I fix this?, is there a different way to deal with this?


  • Admin

    @boriscy

    1. Login.vue is not using Public.vue. Can’t see a <public> tag in there anywhere. Don’t exactly understand what you mean by “when I call the slot from a child component”

    2. You are trying to solve a problem in a bit convoluted way. You should focus on communicating between components rather than making a complex architecture. Communicating between components is a delicate subject. Please read about it here: http://quasar-framework.org/guide/components-sharing-state.html



  • So far I just wanted to pass to the parent component Public.vue from Register.vue or Login.vue a title but I have looked and seems the best way would be using vuex, way to complicated to just pass one parameter.

    Thanks


  • Admin

    @boriscy This is just how Vue works. But you can make a simple store like in Quasar docs link I gave you and import in all components that share the title.