how can I layout my page by vuetify grid system? - vuetify.js

I'm new on vuetify and I'm a little confused by its grid system. I think we have just a v-container tag and after that just a v-row tag. v-col is a direct child of v-row and in v-col we shouldn't have any v-row. right?

Wrong. You can nest v-rows and v-cols. The only difference is that v-col, as you mentioned yourself, must be a direct child of v-row. Otherwise you can nest v-rows inside other v-rows, or inside v-cols, or inside v-container.
Try it yourself here. Just change the v-card inside v-col to v-row with some text and see how it works.
<v-row
:align="align"
no-gutters
style="height: 150px;"
>
<v-col
v-for="n in 3"
:key="n"
>
<v-row no-gutters>Row {{n}}</v-row>
</v-col>
</v-row>

Related

"Tonal" dropdown in autocomplete

I am using vuetify 3.0.0.
I would like to have a v-select or v-autocomplete where the dropdown menu is styled as variant="tonal".
For other v-menus, I have achieved this by wrapping the v-menu in a v-card and setting the v-card to variant="tonal". For the v-select, I can only envision to set the list-items to variant="tonal". However, the top and bottom of the list remain in their original color. Also, I cannot find a menu slot in the documenation that I could potentially use to wrap the menu with a v-card.
Any idea on how to best do that?
https://codepen.io/drhouse82/pen/PoaNgEd
<v-autocomplete
color="primary"
:items="itemList"
v-model="selectedValue">
<template v-slot:item="{ props, item }">
<v-list-item v-bind="props" variant="tonal">
</v-list-item>
</template>
</v-autocomplete>

How can I save order of v-cards when using vue draggable?

I designed a site using Vue, Vuetify, and implemented Draggable really late in the development of my application and used it as follows:
<draggable v-model="dragitems" class="v-card" handle=".handle">
<v-row>
<v-col>
<v-card>
<v-card-title class="text-button"><v-icon color="#8cd0ff" class="handle">mdi-drag</v-icon>Title 1</v-card-title>
</v-card>
</v-col>
</v-row>
<v-row>
<v-col>
<v-card>
<v-card-title class="text-button"><v-icon color="#8cd0ff" class="handle">mdi-drag</v-icon>Title 2</v-card-title>
</v-card>
</v-col>
</v-row>
</draggable>
This works exactly how I want for dragging around cards. There is a handle on each card and all of them response as expected; however, I am wondering how I can save the order of these cards without totally revamping my code, or if its even possible. My implementation of this doesn't seem to align with any of the Draggable documentation examples. Any ideas on how to save the order of v-cards, so they can be reloaded later in the same order?
Thanks

How to relatively position Vuetify v-menu while triggering from v-model?

I'd like to use a v-menu component in Vuetify to appear below a text field, but I need to be able to trigger the menu from a method. I can do that with v-model on the menu, but the menu appears at the top left corner of the screen. If I add absolute :position-x="0" :position-y="0" to the v-menu, I can change the position but it's still relative to the entire screen, not the parent div that it's declared in. When I look at the final HTML, it looks like the menu has been put as a child of the v-app container, which explains why it ends up where it does.
Is there some way I can position the menu relative to a page element while still triggering the menu from a method? Or, to put it another way, is it possible to position the menu relative to an element/component that has nothing to do with the menus activation?
<div style="position:relative">
<v-text-field v-model="orgName" label="Organisation Name"></v-text-field>
<v-menu v-model="showMenu">
<v-list>
<v-list-item v-for="(entry, i) in entries" :key="i">
<v-list-item-title>{{ entry }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>

Element disappeared while toggle v-if and v-else with different templates in v-menu activator

While toggling two different activator templates in v-menu
<v-menu offset-y>
<template v-if="mini" v-slot:activator="{ on }">
<v-list-item v-on="on">
<v-list-item-content>
<v-list-item-title>Jane Smith</v-list-item-title>
<v-list-item-subtitle>Logged In</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
<template v-else v-slot:activator="{ on }">
<v-btn v-on="on">
Login
</v-btn>
</template>
<v-list>
<v-list-item>Position 1</v-list-item>
<v-list-item>Position 2</v-list-item>
<v-list-item>Position 3</v-list-item>
</v-list>
</v-menu>
we have each of them are disappeared after switching back.
All works only if there is an identical root element in each template.
This is for Vuetify 2.0.3
Example: https://codepen.io/anon/pen/aeyeNv
Try 'Click Me' button to toggle it.
I can't speak to why vuetify doesn't handle a different kind of child element, I haven't had a look into the source.
However if you want it to work with different root elements, you can use the mini variable as the key for the parent element (v-menu) which will re-create the component, so it won't be an issue
<v-menu offset-y :key='mini'>
...
</v-menu>
This is a bit of a hack, but it works and sometimes that's enough...

Removing Margins and Padding within Vuetify

So I'm pretty much brand new to Vuetify and Front End development, so sorry if my question is either simple or maybe even too vague.
I'm trying to build a website with Nuxt and Vuetify, but I'm having an issue with removing the padding around the edges of the pages. I've tried using different components within Vuetify such as fluid, I've tried finding and altering the container css code (which I'm not even convinced I've actually found), I've tried just about anything I have found on Stack Overflow or on the Vuetify github, but nothing is working for me.
Does anyone have some advice on how to actually go about having the container take up the whole page instead of leaving margins and padding on the side? I've spent at least 5 hours over the past 2 days trying to figure this out. This is what I currently have.
use spacing helpers:
class="ma-0" removes margins
class="pa-0" removes padding
class="ma-0 pa-0" removes both
Note that these are also props but only for some (grid) components so for example:
<v-text-field class="pa-0"></v-text-field> will work,
and <v-text-field pa-0></v-text-field> will not work.
If in some components you can't remove spacing with these classes, then you need to target relevant elements with CSS.
Ok, so I was able to figure out what I was doing wrong.
Here
<template>
<v-app light>
<v-toolbar fixed app :clipped-left="clipped" color="deep-orange accent-3">
<v-toolbar-side-icon #click="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title v-text="title"></v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-content>
<v-container >
<nuxt/>
</v-container>
</v-content>
<v-footer :fixed="fixed" app>
</v-footer>
</v-app>
So, in my source, everything is laid out in the "default.vue" page, which is here. I was trying to alter the styling in the actual page, so like in index.vue. When I took a closer look at default.vue, I saw the v-container, which I hadn't noticed before (like I said, complete beginner, so this is all pretty new to me).
I was able to add
<style>
.container{
max-width: 100vw;
padding:0px;
}
</style>
to default.vue, which corrected the issue I was dealing with. It really just came down to understanding the template in which I'm working with, and finding the correct place to override the CSS.
They also have predefined spacing helpers, ie pa-0.
https://vuetifyjs.com/en/layout/spacing
To remove paddings from cols, you can add "no-gutters" atribute to v-row:
<v-container fluid>
<v-row no-gutters>
<v-col>
...
</v-col>
</v-row>
<v-container>
One good way to handle these scenarios is to use a fluid v-container on your main Nuxt entry point like this (default layout):
<template>
<v-app>
<v-main>
<v-container fluid>
<Nuxt /> <!-- Nuxt's entry point -->
</v-container>
</v-main>
</v-app>
</template>
And now every time you need a full-width section set the container's v-col padding to zero (best is to use pa-0 or px-0 to be specific).
For example, inside my component I have:
<template>
<v-row class="image-background">
<v-col class="pa-0">
<v-container>
<v-row>
<v-col>
<h2 class="text-h2">Some Text</h2>
</v-col>
</v-row>
</v-container>
</v-col>
</v-row>
</template>
<style scoped>
.image-background {
background-image: url("/images/your-image.jpg");
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 25%;
min-height: 35vh;
}
</style>
To create a full-width section add pa-0 class to it's column element (v-col).
class of .image-background simply adds an background image taking whole width of screen (since it is inside a fluid container with no padding on it's v-col parent).
Notice how I used another container (without fluid attribute) to hold it's content in a responsive manner including it's paddings and media query breakpoints.
I am using Vuetify v2.6.1 and by the way if you're on a vanilla Vue environment this is the whole structure in one piece:
<template>
<v-app>
<v-main>
<v-container fluid>
<v-row class="some-class">
<v-col class="pa-0">
<!-- everything below will take full-width -->
<!-- unless inside another normal v-container -->
<img src="/path/to/image">
<!-- wrap other content inside another v-container -->
<v-container>
<v-row>
<v-col>
<h2 class="text-h2">Some Text</h2>
</v-col>
</v-row>
</v-container>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>

Resources