Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make my v-container fill all height available?

So I'm using vuetify 2.0 within my vue.js app and I'm trying to make my v-container in my Main.vue to take all the height available using fill-height and fluid but it doesn't seem to work at all.

What I currently have is looking like this :

Screenshot: https://imgur.com/K1yOhWu

App.vue

<template>
    <v-app>
        <div v-if="connected">
            <Main />
        </div>
        <div v-else>
            <Login />
        </div>
    </v-app>
</template>

<script>
import Main from '@/views/Main'
import Login from '@/views/Login'

  export default {
    components: {
      Main,
      Login
    },
    data: () => ({
      connected: true
    })

  }
</script>

Main.vue

<template>
    <div>
        <v-navigation-drawer app clipped dark>
            <v-list>
                <v-list-item link>
                    <v-list-item-action>
                        <v-icon>mdi-view-dashboard</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Profil</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
                <v-list-item link>
                    <v-list-item-action>
                        <v-icon>mdi-settings</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Chat</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </v-list>
        </v-navigation-drawer>

        <v-content>
            <v-container class="fill-height"
                         fluid>
                <v-row class="fill-height chat-area" style="background-color: red">
                    <v-col>
                        <p>yooo</p>
                    </v-col>
                </v-row>

                <v-row class="text-field-area" style="background-color: green">
                    <v-col>
                        <v-text-field outlined
                                      rounded
                                      label="Type your message"
                                      hide-details
                                      append-icon="mdi-send"
                                      @click :append="logger()"></v-text-field>
                    </v-col>
                </v-row>
            </v-container>
        </v-content>
    </div>
</template>

<script>
    export default {
        data: () => ({}),
        methods: {
            logger() {
                //eslint-disable-next-line
                console.log("Yes tu as cliqué")
            }
        }
    }
</script>

<style scoped>
    .text-field-area {
        position: relative;
        bottom: 0;
        top: 85%;
        width: 100%;
        align-items: center;
    }

    .chat-area {
        position: relative;
        top: 0;
        bottom: 15%;
        width: 100%;
    }
</style>

What I want to achieve is something like this:

Screenshot: https://imgur.com/tovWwaG

like image 492
Pandorque Avatar asked Jan 21 '20 12:01

Pandorque


3 Answers

fill-height and, in general, all flexbox related properties rely strictly on parent-child relations.

So when you insert a <div> in between the parent and the child, they stop working. To learn more about how flexbox works, I recommend A complete guide to flexbox.

In short, your layout:

<v-app>
  <div v-if="connected">
    <Main />
  </div>
  <div v-else>
    <Login />
  </div>
</v-app>

breaks the parent-child relation (between <v-app> and <Main>).

You can get rid of the extra <div>s in two ways:

  1. Simply place the v-if on the contents:
<v-app>
  <Main v-if="connected" />
  <Login v-else />
</v-app>
  1. Or use <template> tags. Because they're only logical wrappers, Vue doesn't produce actual DOM elements for them. This is particularly helpful when you have multiple elements as content and you don't want to place the v-if on each:
<v-app>
  <template v-if="connected">
    <Main />
    <SomeOtherComponent />
    <YetOtherComponent />
  </template>
  <Login v-else />
</v-app>

Obviously, if you have more than one component in the v-else case, you can turn that into a <template> as well.


Note of caution: because <template> doesn't actually produce a DOM element, when you use it with v-for, you'll have to :key its children instead of the <template>, but except this edge-case, it's a great way to couple layout components without having them wrapped into a DOM element.
It's also useful when you're dealing with strict parent/child HTML relations (i.e: <table> + <tr> + <td>, <ul> + <li>, <ol> + <li>, etc...).

like image 118
tao Avatar answered Sep 22 '22 22:09

tao


Here is what is working for me:

  <v-container fluid style="height: 100vh;" >
    <v-layout fill-height>
        ...
    </v-layout>
  </v-container>
like image 29
Andrew Zagarichuk Avatar answered Sep 21 '22 22:09

Andrew Zagarichuk


just set to fill-height to true, like this

<v-container fill-height> </v-container>

if does not work, put it in v-content, just try this one

<v-content>
   <v-container fill-height>
       <v-layout>
            <v-flex xs12>
                    ...
                    ...
            </v-flex>
       </v-layout>
   </v-container>
</v-content>

Or

<v-content>
    <v-container class="fill-height" fluid>
         <v-row justify="center" align="center">
             <v-col class="shrink">
                  ...
                  ...
            </v-col>
         </v-row>
    </v-container>
</v-content>
like image 3
Qonvex620 Avatar answered Sep 19 '22 22:09

Qonvex620