Как отобразить два v-navigation-ящика рядом друг с другом и иметь возможность скрыть правый от левого?

#vuejs2 #vuetify.js #v-navigation-drawer

#vuejs2 #vuetify.js #v-navigation-drawer

Вопрос:

С помощью Vuetify я хотел бы отобразить два v-navigation-drawer s рядом друг с другом и иметь возможность скрыть правый с помощью кнопки внутри левого. Мой текущий код (см. Ниже) отображает правый ящик над левым, но я хочу, чтобы он отображал правый ящик рядом с левым (см. Экраны ниже).

Я попытался найти что-нибудь полезное в официальной документации и просмотрел несколько разных примеров шаблонов, но в моем случае ничего не помогло.

Я смог придумать следующий код:

 <template>
  <v-app dark>
    <v-navigation-drawer v-model="leftMenu" app clipped>
      <v-container ma-0 pa-0>
        <v-toolbar flat>
          <span>Some helper toolbar</span>
        </v-toolbar>
      </v-container>

      <v-container pa-1 mt-1>
        <v-layout row wrap>
          <v-list>
            <v-list-tile>
              <v-list-tile-action>
                <span><a @click.stop="toggleRightMenu"><v-icon>android</v-icon> Task Menu</a></span>
              </v-list-tile-action>
            </v-list-tile>
            <v-list-tile>
              <v-list-tile-action>
                <span><v-icon>android</v-icon> Menu Element #1</span>
              </v-list-tile-action>
            </v-list-tile>
          </v-list>
        </v-layout>
      </v-container>
    </v-navigation-drawer>

    <v-navigation-drawer v-model="rightMenu" app clipped>
      <v-container>
        <v-layout>
          <v-list>
            <v-list-tile>
              <v-list-tile-action>
                <span><v-icon>android</v-icon> Testing...</span>
              </v-list-tile-action>
            </v-list-tile>
          </v-list>
        </v-layout>
      </v-container>
    </v-navigation-drawer>

    <v-toolbar app clipped-left>
      <v-toolbar-side-icon @click="leftMenu = !leftMenu"></v-toolbar-side-icon>
      <v-toolbar-title class="headline">
        <span>Testing...</span>
      </v-toolbar-title>
      <v-spacer></v-spacer>
    </v-toolbar>

    <v-content>
      <router-view/>
    </v-content>

    <v-footer app>
      <span>Footer</span>
    </v-footer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      leftMenu: true,
      rightMenu: false
    }
  },
  methods: {
    toggleRightMenu() {
      this.rightMenu = !this.rightMenu;
    }
  }
}
</script>
  

В настоящее время у меня есть следующее:https://i.ibb.co/txdN0X8/current-drawer.png

Я ищу что-то подобное:https://i.ibb.co/b514yyC/target-drawer.png

Комментарии:

1. Вместо использования скриншота (я предполагаю, что это так), можете ли вы использовать codepen для этого?

Ответ №1:

Хитрость заключается в том, чтобы иметь v-layout , который заполняет высоту и содержит оба навигационных ящика.

Еще одна вещь, которую вам нужно обязательно применить, — это иметь z-index в обоих навигационных ящиках. В противном случае, когда вы переключаете правую навигацию, она будет отображаться в верхней части левой навигации. И когда вы хотите переключить левую навигацию, вам на самом деле нужно переключать оба.

Я создал Codepen, используя ваш пример данных.

 <v-toolbar flat>
  <v-toolbar-side-icon @click="toggleLeftMenu"></v-toolbar-side-icon>
  <v-toolbar-title class="headline">
    <span>Testing...</span>
  </v-toolbar-title>
  <v-spacer></v-spacer>
</v-toolbar>
<v-layout fill-height>
  <v-navigation-drawer
    style="z-index: 2"
    dark
    clipped
    stateless
    v-model="leftMenu"
  >
    <v-container ma-0 pa-0>
      <v-toolbar flat>
        <span>Some helper toolbar</span>
      </v-toolbar>
    </v-container>
    <v-list>
      <v-list-tile>
        <v-list-tile-action>
          <v-icon @click="rightMenu = !rightMenu">android</v-icon>
        </v-list-tile-action>
        <v-list-tile-content>
          <v-list-tile-title>Task Menu</v-list-tile-title>
        </v-list-tile-content>
      </v-list-tile>
      <v-list-tile>
        <v-list-tile-action>
          <v-icon>android</v-icon>
        </v-list-tile-action>
        <v-list-tile-content>
          <v-list-tile-title>Menu Element #1</v-list-tile-title>
        </v-list-tile-content>
      </v-list-tile>
    </v-list>
  </v-navigation-drawer>
  <v-navigation-drawer
    dark
    style="z-index: 1"
    v-model="rightMenu"
    class="pb-0"
    stateless
  >
    <v-list>
      <v-list-tile>
        <v-list-tile-action>
          <v-icon>android</v-icon>
        </v-list-tile-action>
        <v-list-tile-content>
          <v-list-tile-title>Testing right nav</v-list-tile-title>
        </v-list-tile-content>
      </v-list-tile>
    </v-list>
  </v-navigation-drawer>
</v-layout>
  

Надеюсь, это поможет 🙂

Комментарии:

1. Спасибо, это выглядит хорошо. Единственная проблема, которую я вижу, заключается в том, что когда правое меню закрыто, и я хочу закрыть левое с помощью toggleLeftMenu , левое меню закрыто, но появляется правое меню.

2. Итак, когда правое меню закрыто, а вы закрываете левое меню, чего вы ожидаете? просто чтобы увидеть нужное меню или закрыть их оба, как codepen.io/djshan/pen/PgddLd

3. Когда правое меню закрыто, и я закрываю левое, я бы хотел, чтобы они оба были закрыты. Я думаю, что это codepen.io/djshan/pen/PgddLd это лучшее решение. Спасибо!

4. Еще одна проблема с решением. Когда я хочу добавить контент в приложение, контент попадает под меню, а не прямо в меню. Смотрите здесь: codepen.io/ratk/pen/mgzjoV?editors=1010

5. Проблема в том, что когда у вас есть fill-height на вашем макете, он займет всю ширину. Таким образом, ваш контент переходит на следующую строку. Однако, если вы разместите v-содержимое внутри v-layout , это решит проблему. смотрите

Ответ №2:

Вы могли бы попытаться достичь этого, имея 2 навигационных ящика. Второй margin-left должен быть эквивалентен первому ящику.

Пожалуйста, взгляните на это кодовое перо. Надеюсь, это поможет.

https://codepen.io/Jubels/pen/xeazYY?amp;editable=trueamp;editors=101

 <div id="app">
  <v-app id="inspire">
    <v-layout
      wrap
      style="height: 200px;"
    >
      <v-container>
        <v-layout justify-center>
          <v-btn
            color="pink"
            dark
            @click.stop="drawer = !drawer"
          >
            Toggle Drawer 1
          </v-btn>
          <v-btn
            color="pink"
            dark
            @click.stop="drawer2 = !drawer2"
          >
            Toggle Drawer 2
          </v-btn>
        </v-layout>
      </v-container>

      <v-navigation-drawer
        v-model="drawer"
        :mini-variant="mini"
        absolute
        dark
      >
        <v-list class="pa-1">
          <v-list-tile v-if="mini" @click.stop="mini = !mini">
            <v-list-tile-action>
              <v-icon>chevron_right</v-icon>
            </v-list-tile-action>
          </v-list-tile>

          <v-list-tile avatar tag="div">
            <v-list-tile-avatar>
              <img src="https://randomuser.me/api/portraits/men/85.jpg">
            </v-list-tile-avatar>

            <v-list-tile-content>
              <v-list-tile-title>John Leider</v-list-tile-title>
            </v-list-tile-content>

            <v-list-tile-action>
              <v-btn icon @click.stop="mini = !mini">
                <v-icon>chevron_left</v-icon>
              </v-btn>
            </v-list-tile-action>
          </v-list-tile>
        </v-list>

        <v-list class="pt-0" dense>
          <v-divider light></v-divider>

          <v-list-tile
            v-for="item in items"
            :key="item.title"
            @click=""
          >
            <v-list-tile-action>
              <v-icon>{{ item.icon }}</v-icon>
            </v-list-tile-action>

            <v-list-tile-content>
              <v-list-tile-title>{{ item.title }}</v-list-tile-title>
            </v-list-tile-content>
          </v-list-tile>
        </v-list>
      </v-navigation-drawer>
      <v-navigation-drawer :style="`margin-left: ${drawer ? '300px' :  '0'}`"
        v-model="drawer2"
        :mini-variant="mini"
        absolute
        dark
      >
        <v-list class="pa-1">
          <v-list-tile v-if="mini" @click.stop="mini = !mini">
            <v-list-tile-action>
              <v-icon>chevron_right</v-icon>
            </v-list-tile-action>
          </v-list-tile>

          <v-list-tile avatar tag="div">
            <v-list-tile-avatar>
              <img src="https://randomuser.me/api/portraits/men/85.jpg">
            </v-list-tile-avatar>

            <v-list-tile-content>
              <v-list-tile-title>John Leider</v-list-tile-title>
            </v-list-tile-content>

            <v-list-tile-action>
              <v-btn icon @click.stop="mini = !mini">
                <v-icon>chevron_left</v-icon>
              </v-btn>
            </v-list-tile-action>
          </v-list-tile>
        </v-list>

        <v-list class="pt-0" dense>
          <v-divider light></v-divider>

          <v-list-tile
            v-for="item in items"
            :key="item.title"
            @click=""
          >
            <v-list-tile-action>
              <v-icon>{{ item.icon }}</v-icon>
            </v-list-tile-action>

            <v-list-tile-content>
              <v-list-tile-title>{{ item.title }}</v-list-tile-title>
            </v-list-tile-content>
          </v-list-tile>
        </v-list>
      </v-navigation-drawer>
    </v-layout>
  </v-app>
</div>
  

Комментарии:

1. Спасибо за ваш ответ. Я думаю, что все в порядке, но с этим есть небольшая проблема. Когда вы нажимаете на стрелку, чтобы свернуть меню, меню сворачивается, но остается там, где оно было раньше. Я думаю, что это признак более серьезной проблемы с решениями, зависящими от ручной обработки ширины элементов.

2. ширина — это фактическая опора навигационного ящика, поэтому к ней стоит прислушаться.

Ответ №3:

Я сделал это как дизайн bitbucket, один фиксированный (мини-вариант), а другой — выдвижнойhttps://codepen.io/admica/pen/PoozMNw?editors=1010

 <div id="app">
  <v-app id="inspire">
    <v-navigation-drawer
      
      
       mini-variant
            mini-variant-width="56"
                         app
                         clipped
                         
          
            
    >
      <v-list dense>
        <v-list-item
          v-for="item in items"
          :key="item.text"
          @click=""
        >
          <v-list-item-action>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-action>
          <v-list-item-content>
            <v-list-item-title>
              {{ item.text }}
            </v-list-item-title>
          </v-list-item-content>
        </v-list-item>
        <v-subheader class="mt-3 grey--text text--darken-1">SUBSCRIPTIONS</v-subheader>
        <v-list>
          <v-list-item
            v-for="item in items2"
            :key="item.text"
            @click=""
          >
            <v-list-item-avatar>
              <img
                :src="`https://randomuser.me/api/portraits/men/${item.picture}.jpg`"
                alt=""
              >
            </v-list-item-avatar>
            <v-list-item-title v-text="item.text"></v-list-item-title>
          </v-list-item>
        </v-list>
        <v-list-item
          class="mt-3"
          @click=""
        >
          <v-list-item-action>
            <v-icon color="grey darken-1">add_circle_outline</v-icon>
          </v-list-item-action>
          <v-list-item-title class="grey--text text--darken-1">Browse Channels</v-list-item-title>
        </v-list-item>
        <v-list-item @click="">
          <v-list-item-action>
            <v-icon color="grey darken-1">settings</v-icon>
          </v-list-item-action>
          <v-list-item-title class="grey--text text--darken-1">Manage Subscriptions</v-list-item-title>
        </v-list-item>
      </v-list>
      
      
     
    </v-navigation-drawer>
     
     

    <v-app-bar
      app
      
      color="red"
      dense
    >
      <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
      <v-icon class="mx-3">fab fa-youtube</v-icon>
      <v-toolbar-title class="mr-5 align-center">
        <span class="title">Youtube</span>
      </v-toolbar-title>
      <v-spacer></v-spacer>
      <v-layout
        row
        align-center
        style="max-width: 650px"
      >
        <v-text-field
          :append-icon-cb="() => {}"
          placeholder="Search..."
          single-line
          append-icon="search"
          color="white"
          hide-details
        ></v-text-field>
      </v-layout>
    </v-app-bar>

    <v-content>
      
      <v-container fluid fill-height>
        <v-layout
          
          align-center
          style="position:relative"
        >
          <v-navigation-drawer
        v-model="drawer"
        
        v-if="drawer"
        
        
        
        
        
                          
        
        
      >
        <v-list-item>
          <v-list-item-avatar>
            <v-img src="https://randomuser.me/api/portraits/men/78.jpg"></v-img>
          </v-list-item-avatar>
  
          <v-list-item-content>
            <v-list-item-title>John Leider</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
  
        <v-divider></v-divider>
  
        <v-list dense>
  
          <v-list-item
            v-for="item in items"
            :key="item.title"
            link
          >
            <v-list-item-icon>
              <v-icon>{{ item.icon }}</v-icon>
            </v-list-item-icon>
  
            <v-list-item-content>
              <v-list-item-title>{{ item.title }}</v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list>
      </v-navigation-drawer>
          ahmed ali 
        </v-layout>
      </v-container>
    </v-content>
  </v-app>
</div>