I am currently getting to know the vue framework with vuetify, and I am running into a couple issues here ... I have laid out a simple layout for the main page, but for whatever reason, the buttons do not fill the full height, and the background color is using (by default) the hover color. this is what it looks like:
The Code:
<template>
<v-app>
<v-app-bar app> </v-app-bar>
<v-main>
<router-view />
</v-main>
<v-bottom-navigation app v-model="value">
<v-btn value="cards" to="/cards">
<span>Cards</span>
<v-icon>mdi-cards</v-icon>
</v-btn>
<v-btn value="decks" to="/decks">
<span>Decks</span>
<v-icon>mdi-mail</v-icon>
</v-btn>
</v-bottom-navigation>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
value: 'cards',
}),
}
</script>
it is quite odd that this is happening as the application will randomly fix itself every once in a while when deleting random lines of code, then when I try to change something on the navigation, it will then break again.
Related
Using Vue 2 and Vuetify, I am trying to implement the shrink on scroll threshold app bar found on the Vuetify page.
This works if I create a v-container on the main App.vue page as in the example on Vuetify's website, but it does not work when scrolling content located in a separate View being shown via the Vue router. Everything shows up but the app bar does not shrink when I scroll on the content being included by the router. How do I get the app bar to track the scrolling of the separate view?
App.Vue:
<template>
<v-app id="inspire">
...
<v-app-bar
app
color="#43a047"
dark
shrink-on-scroll
prominent
src="https://picsum.photos/1920/1080?random"
fade-img-on-scroll
scroll-target="#main"
scroll-threshold="500"
>
<template v-slot:img="{ props }">
<v-img
v-bind="props"
gradient="to top right, rgba(55,236,186,.7), rgba(25,32,72,.7)"
></v-img>
</template>
<v-app-bar-nav-icon #click="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Grocery Manager</v-toolbar-title>
</v-app-bar>
<v-main style="overflow: auto" id="main">
<router-view></router-view>
</v-main>
</v-app>
</template>
HomeView.vue
<template>
<div class="home pa-6">
<h1>Home</h1>
... Lots of text ...
</div>
</template>
<script lang="ts">
import Vue from "vue";
//import HelloWorld from "../components/HelloWorld.vue";
export default Vue.extend({
name: "Home",
components: {
// Add components here
},
});
</script>
I use Vuetify in my webapplication. The whole webapplication is responsive.
I have the problem that on smaller screens (Smartphone, Pad) I can zoom out of the website which means that I have a white space on the right of my website.
I don't know how this can happen and it is in every single page of my web application like that. What can I do that I use from beginning the whole space and the user can not zoom out from the website and gets this white space on the left?
Below a short example:
<template>
<v-app>
<v-main>
<v-container>
<v-row justify="center" align="center">
<v-col cols="12" xs="10" sm="10" md="10" lg="10" xl="10">
TEST_COL
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
data: () => ({
}),
}
</script>
<style>
</style>
Maybe the problem is in the App.vue file but I don't see any problem there. To be sure I post the app.vue below:
<template>
<v-app>
<Navbar />
<v-main>
<router-view></router-view>
</v-main>
<Footer />
</v-app>
</template>
I put two screenshots below so you see what i mean.
Thanks!
Chris
I got the answer. I used the <v-navigation-drawer> provided by Vuetify to create a drawer object. I used the following options:
<v-navigation-drawer v-model="drawer" absolute temporary right>
But absolute means it "Applies position: absolute to the component." which means that it takes extra space in the website. The option must be "fixed" instead of "absolute" then it works.
The good settings are:
<v-navigation-drawer v-model="drawer" fixed temporary right>
Now the drawer opens on the right side of the website (better for smartphones) and it doesn't take any absolute space!!
I use vuetify https://vuetifyjs.com/en/
My parent component like this :
<template>
<v-container>
...
<v-col
v-for="(item, i) in items"
:key="i"
>
<v-card
>
<v-app-bar dark color="grey">
<v-toolbar-title>Weekly Schedule : {{item.name}}</v-toolbar-title>
<div class="flex-grow-1"></div>
<modal-datepicker :schedule="item" />
</v-app-bar>
</v-col>
...
</v-container>
</template>
<script>
import { mapState } from "vuex";
import modalDatepicker from "../views/modalDatepicker";
export default {
components: {modalDatepicker},
};
</script>
My child component like this :
<template>
<v-dialog
:ref="dialog"
v-model="modal"
:return-value.sync="date"
>
<template v-slot:activator="{ on }">
<v-btn color="success" dark v-on="on">Show datepicker</v-btn>
</template>
<v-row justify="center">
<v-date-picker v-model="date" scrollable>
<div class="flex-grow-1"></div>
<v-btn text color="primary" #click="modal = false">Cancel</v-btn>
<v-btn text color="primary">OK</v-btn>
</v-date-picker>
</v-row>
</v-dialog>
</template>
<script>
import { mapState } from "vuex";
import modalDatepicker from "../views/modalDatepicker";
export default {
components: {modalDatepicker},
props: ['schedule'],
data: () => ({
date: new Date().toISOString().substr(0, 10),
modal: false,
}),
mounted() {
console.log(this.schedule)
},
};
</script>
The code above works, but seems inefficient. because every time the loop, it call modal dialog. I want modal to only be called when user click show datepicker button
how do i do that?
Apologies as I am on my mobile. Have you considered having the modal in your parent component outside of the loop?
You could have a data variable to handle your modal e.g
modal: {
open: false,
schedule: null }
Essentially then when your button is clicked you could add a v-click with a function that controls this data which in turns handles the content in the modal.
Then on your date picker or modal have a function to handle the update/close to clear this data and handle whatever you need too outside.
Then you could combine this into one component.
I see you have vuex you could also use vuex to control your modal and it’s contents.
I am trying to implement vuetify in my project. I am newbie in VueJs & vuetify too.
I am trying to use a toolbar which contains a rounded image on the right corner. But, It is not responsive. When i open developer option and decrease the screen size to that of mobile. The rounded image does not render.
I tried using plain tags but it is actually disrupting the layout.
Here is the code
VuetifyTest.vue:
<template lang="html">
<v-toolbar>
<v-toolbar-side-icon>
<!-- <v-img src="../assets/mad_logo.png" aspect-ratio="1.7"></v-img> -->
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-layout
align-center
justify-space-around
wrap
>
<v-avatar
:tile= false
size="36"
color="grey lighten-4"
>
<img src="../assets/static.jpeg" alt="avatar">
</v-avatar>
</v-layout>
</v-toolbar-items>
</v-toolbar>
</template>
<script lang="js">
export default {
name: 'VuetifyTest',
props: [],
mounted() {
},
data() {
return {
}
},
methods: {
},
computed: {
}
}
</script>
<style scoped >
</style>
This is how it looks like in laptop screen
This is how it looks like in mobile screen
How do i change the code to make it responsive
PS: I also tried reducing the screen size while viewing here in reduced screen size.
Even though it showed like this..
Even though the official documentation have this problem?
How do i make it responsive..
thanks!
You do not have to specify v-layout within the v-toolbar - if you remove the v-layout and replace it with just the v-avatar, it works.. Examples are below:
[CodePen Mirror]
Snippet:
new Vue({ el: "#app" })
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" rel="stylesheet" />
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-toolbar>
<v-toolbar-side-icon>
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-avatar :tile=false size="36" color="grey lighten-4">
<img src="https://i.pravatar.cc/300?img=3" alt="avatar">
</v-avatar>
</v-toolbar>
</v-app>
</div>
I understand how to use Vuetify's v-tooltip with the tooltip wrapping the component. However, I'm not quite sure how to have the activator button outside.
e.g. I have this (non-working code):
<v-tooltip bottom
:activator="$refs.filterBtn"
>
Filter displayed items
</v-tooltip>
<v-btn
ref="filterBtn"
icon
#click="isFilter = !isFilter"
>
<v-icon>fa-filter</v-icon>
</v-btn>
I also tried using prop activator without the v-bind:, same result
Idea: I want the button to be placed separately from tooltip in order to run unit tests. When testing, shallowMount strips anything inside <v-tooltip> so I can't test the button. The problem is I don't know how to make tooltip show up on hover (just like it does when wrapped), I do not want to trigger it with #click.
EDIT: here's codepen
How about using the v-hover UI Component. Wrap it around your button. Bind a boolean variable to the v-hover using v-model, call it buttonHovering. Then bind a boolean variable to the v-tooltip using v-model, call it showToolTip. Then use a watcher to toggle showToolTip true and false based on the value of buttonHovering. Or you can make showToolTip a computed property that always returns the value of buttonHovering. Lastly, bind the disabled attribute of the v-tooltip to the !buttonHovering property to ensure that the tooltip only displays when hovering over the button and not the tooltip's activator.
new Vue({
el: '#app',
data () {
return {
buttonHovering: false,
showToolTip: false
}
},
watch: {
buttonHovering (newVal) {
this.showToolTip = newVal
}
}
})
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.16/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-card>
<v-card-title>
<v-hover v-model="buttonHovering">
<v-btn large>
Hello
</v-btn>
</v-hover>
<v-spacer></v-spacer>
<v-tooltip left v-model="showToolTip" :disabled="!buttonHovering">
<span>Hi from over here!</span>
</v-tooltip>
</v-card-title>
</v-card>
</v-app>
</div>
Try this:
<v-tooltip bottom
v-model="filterBtnTTip"
>
Filter displayed items
</v-tooltip>
<v-btn
icon
#click="isFilter = !isFilter"
#mouseover="filterBtnTTip = true"
#mouseleave="filterBtnTTip = false"
>
<v-icon>fa-filter</v-icon>
</v-btn>
...
data () {
return {
...
filterBtnTTip: false
}
}
<v-app>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
>
Your button
</v-btn>
</template>
<span> Your hover message </span>
</v-tooltip>
</v-app>
In my case, it was necessary to place the tooltip together with the button in one component (a custom button with a tooltip function). Therefore, I used a prop activator and added the tooltip itself directly to the button:
<template>
<v-btn
:id="id"
>
<span>
<slot></slot>
<v-tooltip
v-if="tooltipText"
:activator="`#${id}`"
top
>
{{ tooltipText }}
</v-tooltip>
</span>
</v-btn>
</template>
<script>
let id = 0;
export default {
data() {
return {
id: `custom-button-${id++}`, //This is how we get a unique id for each created button
}
}
}
</script>
According to the same scheme, you can place v-tooltip anywhere, the main thing is that at the time of mounting the "activator" already exists.