Vuetify v-spacer is not working with v-tabs - vue.js

I need to place logo on left side of navbar and tabs on the right side. I use v-space to do it but it doesn't work. I checked - it works fine with v-btn but not with v-tabs. I use Vue 2 and Vuetify 2.6:
App.vue
<template>
<v-app>
<v-main>
<Navbar />
<router-view/>
</v-main>
</v-app>
</template>
Navbar.vue
<template>
<v-app-bar
app
dense
dark >
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
transition="scale-transition"
width="40"
/>
<v-spacer></v-spacer>
<v-tabs>
<v-tab>Project</v-tab>
<v-tab>Users</v-tab>
<v-tab>Settings</v-tab>
</v-tabs>
</v-app-bar>
</template>
This is what I got:
I wanted menu (tabs) to be aligned to the right. Why v-spacer is not working here?
I also checked this topic https://github.com/nuxt-community/vuetify-module/issues/165 but it also does not solve the issue.

Check this codesandbox I made: https://codesandbox.io/s/stack-70115344-jzhii?file=/src/components/Navbar.vue
There's no need to use a v-spacer. You only need to set the right prop to the v-tabs component.
<v-tabs right>
<v-tab>Project</v-tab>
<v-tab>Users</v-tab>
<v-tab>Settings</v-tab>
</v-tabs>

Try <v-tabs right>
<template>
<v-app-bar
app
dense
dark >
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
transition="scale-transition"
width="40"
/>
<v-tabs right>
<v-tab>Project</v-tab>
<v-tab>Users</v-tab>
<v-tab>Settings</v-tab>
</v-tabs>
</v-app-bar>
</template>

Related

Trouble aligning content inside v-row or v-col in Vuetify.js

I am having issues aligning things correctly inside my Vue app using Vuetify.
<v-card class="mx-auto">
<v-row>
<v-col
v-for="(item, i) in items"
:key="i"
align-end
justify-end
>
<v-btn class="btn">
<v-icon>{{ item.icon }}</v-icon>
<span class="ml-2">{{ item.text }}</span>
</v-btn>
</v-col>
</v-row>
...
I simply want to align it to the right.
The properties you've put on <v-col> don't exist (i.e. align-end and justify-end). They are properties on the <v-row> component (which is a flex container). You need to use classes instead.
Make sure to consult the API->props section on the Vuetify component page when choosing component properties.
Try
<v-col class="d-flex justify-end">
<v-btn>Button</v-btn>
</v-col>
Note that the alignment is dependent upon the width of v-col. If v-col is only as wide as the button, you'll need to set the width by using the cols="x" property.
Add direction: rtl to your v-btn, Here is codepen:
<template>
<v-btn class="btn rtl">
...
</v-btn>
</template>
<style>
.rtl { direction: rtl; }
</style>

V-img in Vue (Vuetify) don't realised in browser contex menu as image

I use Vuetify framework and create v-img element. When I open contex menu in browser there isn't ordinary image options (Save as, Open image, Copy image). I check it on Firefox and Chrome. How can I fix it? I need to add abilities to save images from page.
Vue 2.6.12, Vuetify 2.3.10
My code snippet:
<template>
<v-img
:src="imageSrc"
:alt="imageAlt"
:width="imageWidth"
:min-height="imageMinHeight"
contain
>
<template v-slot:placeholder>
<v-row
class="fill-height ma-0"
align="center"
justify="center"
>
<v-progress-circular
indeterminate
color="blue-grey lighten-3"
></v-progress-circular>
</v-row>
</template>
</v-img>
</template>
The src of image is an url.
I resolve my issue with default slot of v-img. I put <img> with zero opacity to that slot. So it detected as ordinary image by browser.
My example:
<template>
<v-img
:src="imageSrc"
:alt="imageAlt"
:width="imageWidth"
:height="imageHeight"
contain
>
<template v-slot:default>
<div class="d-flex flex-row">
<v-spacer/>
<img
:src="imageSrc"
:height="imageHeight"
align="center"
class="opacity-0"
>
<v-spacer/>
</div>
</template>
<template v-slot:placeholder>
<v-row
class="fill-height ma-0"
align="center"
justify="center"
>
<v-progress-circular
indeterminate
color="blue-grey lighten-3"
></v-progress-circular>
</v-row>
</template>
</v-img>
</template>
css:
.opacity-0 {
opacity: 0 !important;
}

Is there a Vue or Vuetify component that does not render ANY output?

I have a custom navMenu component that I show twice on my page - once across the top, and once hidden in a v-navigation-drawer until the screen width gets small enough to show it:
<template>
<nav>
<v-app-bar app hide-on-scroll>
<template #extension v-if="$vuetify.breakpoint.smAndUp">
<v-container>
<v-row>
<v-spacer />
<navMenu :items="menuItems" />
<v-spacer />
</v-row>
</v-container>
</template>
<v-app-bar-nav-icon
#click="toggleDrawer()"
v-if="$vuetify.breakpoint.xs"
/>
<img id="logo"
alt="corporate logo"
src="#/assets/full_logo.svg"
width="200"
height="60"
/>
<v-spacer />
<h3 class="info--text headline">My Fancy Website</h3>
</v-app-bar>
<v-navigation-drawer app
v-model="drawer"
v-if="$vuetify.breakpoint.smAndDown">
<navMenu :items="menuItems" />
</v-navigation-drawer>
</nav>
</template>
NavMenu.vue
<template>
<v-col v-for="(item, index) in items" :key="index">
<div v-if="item.children">
<v-menu transition="slide-y-transition" bottom>
<template #activator="{ on }">
<v-btn text v-on="on">{{ item.label }}</v-btn>
</template>
<v-list>
<v-list-item
v-for="(child, j) in item.children"
:key="j"
router
:exact="child.exact"
:to="{ name: child.routeName }"
>
<v-list-item-title class="text-capitalize">
{{ child.label }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
<div v-else>
<v-btn text router :to="{ name: item.routeName }" :exact="item.exact">
{{ item.label }}
</v-btn>
</div>
</v-col>
</template>
...you may have noticed a fatal flaw in my component: you can't iterate on a root element! Simple enough, wrap it in a <div />, right? Wrong. Wrapping the contents of the template in a div really screws up the layout of the menu items - it renders them stacked vertically instead of horizontally - I think the CSS is looking for a direct child or something.
Is there some alternative element that I can use for the template to satisfy the "one root element" edict that doesn't render any output? Oh, and I tried using the <template /> element already - you can't use it as a root element.
You were so close to finding the answer...
Actually, you should put in a div container, but then just change the display property of the container so the items are still positioned horizontally:
NavMenu.vue
<template>
<div style="display: flex">
<v-col v-for="(item, index) in items" :key="index">
...
I updated your code below. Essentially, all you need to do is to move the entire <v-navigation-drawer> component into your NavMenu.vue file and add the additional drawer prop. Since the <v-navigation-drawer component doesn't actually do much on its own. The #input event listener is only so that you can have the parent component update the drawer value outside of the child component.
<template>
<nav>
<v-app-bar app hide-on-scroll>
<template #extension v-if="$vuetify.breakpoint.smAndUp">
<v-container>
<v-row>
<v-spacer />
<navMenu :items="menuItems" />
<v-spacer />
</v-row>
</v-container>
</template>
<v-app-bar-nav-icon
#click="toggleDrawer()"
v-if="$vuetify.breakpoint.xs"
/>
<img id="logo"
alt="corporate logo"
src="#/assets/full_logo.svg"
width="200"
height="60"
/>
<v-spacer />
<h3 class="info--text headline">My Fancy Website</h3>
</v-app-bar>
<navMenu
v-if="$vuetify.breakpoint.smAndDown"
:drawer="drawer"
:items="menuItems"
#navInput="toggleDrawer()"
/>
</nav>
</template>
NavMenu.vue
<template>
<v-navigation-drawer app :value="drawer" #input="$emit('navInput')>
<v-col v-for="(item, index) in items" :key="index">
<div v-if="item.children">
<v-menu transition="slide-y-transition" bottom>
<template #activator="{ on }">
<v-btn text v-on="on">{{ item.label }}</v-btn>
</template>
<v-list>
<v-list-item
v-for="(child, j) in item.children"
:key="j"
router
:exact="child.exact"
:to="{ name: child.routeName }"
>
<v-list-item-title class="text-capitalize">
{{ child.label }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
<div v-else>
<v-btn text router :to="{ name: item.routeName }" :exact="item.exact">
{{ item.label }}
</v-btn>
</div>
</v-col>
</v-navigation-drawer>
</template>
<script>
export default {
props: {
drawer: Boolean,
items: {
type: Array,
default: () => []
}
}
};
</script>

How to use router-link "to" prop on vuetify components?

I have an avatar image, upon click I'd like to route to one of my paths. I understand I can do it with router-view, but also that vuetify inherits its properties.
What is missing?:
<div id="app">
<v-app>
<v-app-bar>
<v-toolbar-items>
<v-avatar to="'/profile'">
<v-img src="http://www.dumpaday.com/wp-content/uploads/2019/10/00-156-750x280.jpg"></v-img>
</v-avatar>
</v-toolbar-items>
</v-app-bar>
</v-app>
</div>
full example:
https://codepen.io/toit123/pen/GRRmpqq
v-avatar isn't a link abd doesn't support to so you have to wrap your image with a router link like:
<div id="app">
<v-app>
<v-app-bar>
<v-toolbar-items>
<router-link to="/profile">
<v-avatar>
<v-img src="http://www.dumpaday.com/wp-content/uploads/2019/10/00-156-750x280.jpg"></v-img>
</v-avatar>
</router-link>
</v-toolbar-items>
</v-app-bar>
</v-app>
</div>
Or you add a custom click event on the v-avatar and do the routing in a method like
<v-avatar #click="forward">
JS
methods: {
forward() {
this.$router.push("/profile")
}
}

Vuetify sticky header toolbar

I use v-toolbar but when I scroll down it get disappears. Basically I want to a sticky header.
This is my code basically.
<div id="app">
<v-app>
<v-toolbar dense>
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-btn flat>Link One</v-btn>
<v-btn flat>Link Two</v-btn>
<v-btn flat>Link Three</v-btn>
</v-toolbar-items>
</v-toolbar>
<main>
<h1 v-for="n in 20" :key="n">{{n}}</h1>
</main>
</v-app>
</div>
Edit: Vuetify version 1.5:
You just need to add fixed to your v-toolbar which fixes the position, So:
<v-toolbar dense fixed>
You can see the documentation here
Version 2.0.0
Change from vuetify version 1.5 :
v-app-bar: Brand new component that was created to better scope the functionality of v-toolbar. All existing scrolling techniques and app functionality from v-toolbar has been moved. New scrolling techniques such as collapsing bar, scroll shrink and more have been added.
<v-app-bar fixed> would fix the toolbar. Documentation
Try this code.
<v-app id="inspire">
<div
class="hide-overflow"
style="position: relative;"
>
<v-toolbar
color="teal lighten-3"
dark
scroll-off-screen
scroll-target="#scrolling-techniques"
dense
>
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-btn flat>Link One</v-btn>
<v-btn flat>Link Two</v-btn>
<v-btn flat>Link Three</v-btn>
</v-toolbar-items>
</v-toolbar>
<main id="scrolling-techniques" class="scroll-y"
style="max-height: 625px;">
<h1 v-for="n in 20" :key="n">{{n}}</h1>
</main>
</div>
</v-app>
For those who just wants to have a sticky element either above or below,
you might want to try snackbars
<v-snackbar v-model="snackbar" timeout="-1" top app>
jojojojojo asdfjasldf
</v-snackbar>