javascriptvue.jsvuejs2vue-componentvue-material

Layout components (drawer, toolbar, …) not working as component


I'm using vue with vue-material.

I'm currently working to layout the main structure of my web app, using md-app as root for md-[app-]drawer, md-[app-]toolbar and md-[app-]content.

If I place these components directly in the md-app tag, they work. This looks like this:

<template>
  <div class="md-layout-row">
    <md-app>
      <md-drawer>
        <md-list>
          <md-list-item>
            <md-icon>people</md-icon>
            <span class="md-list-item-text">Foo</span>
          </md-list-item>

          <md-list-item>
            <md-icon>view_list</md-icon>
            <span class="md-list-item-text">Bar</span>
          </md-list-item>
        </md-list>
      </md-drawer>
    </md-app>
  </div>
</template>

But for design purpose I try to extract each of those inner parts (in this case the md-drawer tag) into own vue components.

Problem

I have my Drawer Compnonent now, it looks like this:

<template>
  <md-drawer>
    <md-list>
      <md-list-item>
        <md-icon>people</md-icon>
        <span class="md-list-item-text">Foo</span>
      </md-list-item>

      <md-list-item>
        <md-icon>view_list</md-icon>
        <span class="md-list-item-text">Bar</span>
      </md-list-item>
    </md-list>
  </md-drawer>
</template>

.. and my md-app (after importing the component ofc) looks now like this:

<template>
  <div class="md-layout-row">
    <md-app>
      <MyDrawer />
    </md-app>
  </div>
</template>

But this doesn't render the drawer at all. Why is this? Does Vue wrap components additionally which may mess with the css of vue-material? Is there a way to bypass/fix this issue? .. or am I just using it the wrong way?

Addition (Edit 1)

After some experiments I figured out that it works if surround MyDrawer tag with a md-[app-]content tag, but this doesn't result in the layout I'm looking for.

I guess md-app is looking for specifically these components, and because it doesn't know what to do with a MyDrawer tag it just ignores it? Although MyDrawer is essentially a md-drawer tag/component?

Addition (Edit 2)

I've been reading about DOM Template Parsing Caveats, I figured this should work but I didn't have any success yet. I just declared a <md-drawer is="MyDrawer" /> tag and removed the main wrapping md-drawer tag from MyDrawer component


Solution

    1. using the component incorrectly doc

    md-active - type = Boolean. Option used to trigger the drawer visibility. Should be used with the .sync modifier. Default = false

    example using for Drawer:

    <md-drawer :md-active.sync="showNavigation">
      ...
    </md-drawer>
    
    1. md-app incorrect. see Component-Naming-Conventions

    example using for md-app:

    <md-app>
      <my-drawer />
    </md-app>
    

    *note but before using look at the next answer

    1. Addition (Edit 1) - incorrect.

    Any other tag passed as a direct child of the md-app tag will be ignored. The component will only look for those three tags and choose the right placement for them. Documentation

    example using for md-app:

    <md-app md-waterfall md-mode="fixed-last">
      <md-app-toolbar class="md-large md-dense md-primary">
        <div class="md-toolbar-row">
          <div class="md-toolbar-section-start">
            <md-button class="md-icon-button" @click="menuVisible = !menuVisible">
              <md-icon>menu</md-icon>
            </md-button>
            <span class="md-title">My Title</span>
          </div>
    
          <div class="md-toolbar-section-end">
            <md-button class="md-icon-button">
              <md-icon>more_vert</md-icon>
            </md-button>
          </div>
        </div>
    
        <div class="md-toolbar-row">
          <md-tabs class="md-primary">
            <md-tab id="tab-home" md-label="Home"></md-tab>
            <md-tab id="tab-pages" md-label="Pages"></md-tab>
          </md-tabs>
        </div>
      </md-app-toolbar>
    
      <md-app-drawer :md-active.sync="menuVisible">
        <md-toolbar class="md-transparent" md-elevation="0">Navigation</md-toolbar>
        <md-list>
          <md-list-item>
            <md-icon>move_to_inbox</md-icon>
            <span class="md-list-item-text">Inbox</span>
          </md-list-item>
        </md-list>
      </md-app-drawer>
    
      <md-app-content>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
      </md-app-content>
    </md-app>
    
    1. Addition (Edit 2) - incorrect. is not matter in your case. see using API and Component-Naming-Conventions

    just use tag: <md-drawer/>

    UPDATE

    How to use custom Drawer in md-app.

    drawer must be wrapped in md-app-drawer

    Example

    code:

    <md-app-drawer :md-active.sync="menuVisible">
      <custom-drawer/>
    </md-app-drawer>
    

    App

    Component