Open Vue dialog(modal) on parent - javascript

First of all, i've already read this post but it didn't help me (or i wasn't able to solve with that)
I've got a component which is a Vuetify Modal (ModalTurno.vue).
I'm trying to open this from a button in my Bottom Nav (bottomNav.Vue) (also a component).
I was even able to do that! but it opens on the Bottom Nav div. So I'd like to open this on my main vue (Turno.Vue) so i'll be able to see the whole modal. This is driven me crazy
Vuetify Modal (ModalTurno.Vue):
<template>
<v-dialog v-model="dialog" persistent max-width="500px" >
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
</v-card>
</v-dialog>
</template>
<script>
export default {
data: () => ({
dialog: false
})
}
</script>
Bottom Nav (bottomNav.Vue) (Where the button is):
<template>
<v-card height="200px" flat>
<v-bottom-nav
:value="true"
color="indigo"
fixed
>
<v-btn
dark
flat
value="favorites">
<span>Agregar turno</span>
<v-icon>add_circle</v-icon>
</v-btn> <!--THIS IS THE BUTTON TO OPEN THE DIALOG -->
</v-bottom-nav>
</v-card>
</template>
<script>
export default {
name: 'header',
data () {
return {
bottomNav: 'recent'
}
}
}
</script>
Turno.Vue (Where the modal should be displayed):
<template>
<div>
<bottomNav> </bottomNav>
<modalTurno> </modalTurno>
</div>
</template>
<script>
import bottomNav from "./components/bottomNav.vue";
import modalTurno from "./components/ModalTurno.vue";
export default {
name: 'turno',
components: {
bottomNav,
modalTurno
}
}
</script>
Thanks to everyone who use his/her time to read this post!

You could do this by :
in Turno.vue
add ref="modalTurno" to (to make this component accessible via this.$refs.modalTurno - Accessing Child Component Instances & Child Elements)
in bottomNav.Vue
add #click="$parent.$refs.modalTurno.dialog = true" to v-btn (this will update dialog in modalTurno)

Related

I need add other component with this button

this button component's, I need to click and pull another component with it, but I don't know how to do that, look at the return plantioComp, this is the component I want this button to call.
<template>
<div class="btn-center">
<v-btn class="mx-1" fab dark v-on:click="propri" type="submit">
<v-icon dark> mdi-plus </v-icon>
<p class="text-btn">Plantio</p>
</v-btn>
</div>
</template>
<script>
import plantioComp from './plantioComp.vue'
export default {
name: 'btnAdd',
methods: {
propri () {
// alert('here')
return plantioComp
}
}
}
</script>
It's not clear what you mean by calling another component on click or what plantioComp is. I assume you mean to make the component displayed? If so, it needs to be added to the template. If you have a condition where it needs to display only after a button click, you can create a boolean data variable that is initially false and then set to true on button click. Using a v-if directive on plantioComp you can have it display once the variable is true.
<template>
<div class="btn-center">
<v-btn class="mx-1" fab dark v-on:click="showPlantio=true" type="submit">
<v-icon dark> mdi-plus </v-icon>
<p class="text-btn">Plantio</p>
</v-btn>
</div>
<plantioComp v-if="showPlantio" />
</template>
<script>
import plantioComp from './plantioComp.vue'
export default {
name: 'btnAdd',
data() {
return {
showPlantio: false
}
}
}
</script>
I think your app is using vuetify. If you are specifically trying to show a modal, I would suggest using the v-dialog component.

Vue Vuetify Performance/Freeze Issue

I'm building an vue2.js app, which gets data from an API and shows it within an vuetify data-iterator and on a leaflet map.
The App.vue component handles the communication between the other components (FilterPanel, ListPanel and MapPanel) ...
<template>
<div id="app">
<v-app id="inspire">
<v-app>
<v-navigation-drawer app width="26em" class="pb-16 pb-lg-0">
<FilterPanel #change="getData" />
</v-navigation-drawer>
<v-sheet id="widget-panel" app class="open" :elevation="8">
<v-container
class="grey lighten-5 scrollContainer"
style="display: flex; overflow-y: auto; flex: 1"
>
<ListPanel :loading="loading" :data="data">
<template #card="{ data }">
<DataCard :data="data" :id="'data' + data.id"></DataCard>
</template>
</ListPanel>
</v-container>
</v-sheet>
<v-main>
<MapPanel :loading="loading" :data="data" />
</v-main>
</v-app>
</v-app>
</div>
</template>
.. and the the API call to get the data.
...
methods: {
getData() {
this.loading = true;
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((json) => (this.data = json))
.finally(() => (this.loading = false));
},
},
...
Within the ListPanel.vue component an slot is defined, so it can be used somewhere else with other data visualization.
<template>
<v-data-iterator
no-results-text="no - data"
loading="loading"
loading-text="loading - data"
no-data-text="no - data"
:items="data"
hide-default-footer
disable-pagination
>
<template v-slot:default="props">
<v-row>
<v-col v-for="item in props.items" :key="item.id" cols="12">
<slot name="card" :data="item">
no slot provided
</slot>
</v-col>
</v-row>
</template>
</v-data-iterator>
</template>
<script>
export default {
name: "ListPanel",
props: ["data", "loading"],
};
</script>
The MapPanel.vue component shows all data entries on the map with clickable markers, which will open popups to show some information about the data. The map also holds an loading indicator (v-progress-linear) to show if data is loading or not.
<template>
<l-map
id="map"
ref="myMap"
:style="styleObject"
v-if="showMap"
:zoom="zoom"
:center="center"
:options="mapOptions"
>
<v-progress-linear
style="z-index: 800 !important"
:indeterminate="loading"
:active="loading"
absolute
top
color="info"
></v-progress-linear>
<l-tile-layer :url="url" :attribution="attribution" />
<l-control-zoom position="bottomright"></l-control-zoom>
<l-marker
v-for="(item, index) in markers"
:key="'marker-' + index"
:lat-lng="item.location"
>
<l-popup :options="getPopupOptions(item.id)">
<DataCard :data="item" showRequest flat></DataCard>
</l-popup>
</l-marker>
</l-map>
</template>
For better visual representation I'm using an reusable component (DataCard) with v-card to show the necessary data.
I have setup a simplified version of the app. https://codesandbox.io/s/sleepy-hoover-s5w5l
Loading the app or getting the data, let the app freezes for some seconds. You'll see it at the progress bar on the top. The animation stops!
I figured out, that the v-card component is slowing down the whole app. If I remove the card component entirely, loading the data seems to work just fine.
Getting the data from the API isn't the problem, since getting the data from it is very fast.
Vue DevTools Extension within FireFox shows Problems with the Map Markes and the DataCard component.
So I'm asking, what I'm doing wrong with the DataCard Component ?

Create static left navbar component with Vue

I need a vertical navbar to the left of my app's layout, and with the content all across the right.
As it stands, I can't do that. My navbar pushes all the content down. How can I fix this?
This is what my App.vue's template looks like:
<template>
<div id="app">
<v-app>
<navbar/>
<v-main>
<v-container class="main-container">
<router-view/>
</v-container>
</v-main>
</v-app>
</div>
</template>
For the navbar component I am using vuetify, specifically the mini navbar
As per the example code, here is what it currently looks like:
<template>
<v-navigation-drawer
v-model="drawer"
:mini-variant.sync="mini"
permanent
>
<v-list-item class="px-2">
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/men/85.jpg"></v-img>
</v-list-item-avatar>
<v-list-item-title>John Leider</v-list-item-title>
<v-btn
icon
#click.stop="mini = !mini"
>
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
</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>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
#Component<Navbar>({})
export default class Navbar extends Vue {
private value: string = 'home';
private drawer: boolean = true;
private items: Array<Object> = [
{ title: 'Home', icon: 'mdi-home-city' },
{ title: 'My Account', icon: 'mdi-account' },
{ title: 'Users', icon: 'mdi-account-group-outline' }
]
private mini: boolean = true;
}
</script>
As mentioned on the top, this is still just pushing all the app's content down. This is what it currently looks like:
What can I do so that on the left I have my navbar but on the right
Edit: For the sake of clarification, I do want the navbar to be vertical, but I just don't want it to push down all the content. Basically I want my app to have a side navigation
Wrap the navbar and main in a <v-row>:
<template>
<div id="app">
<v-app>
<v-row>
<navbar/>
<v-main>
<v-container class="main-container">
<router-view/>
</v-container>
</v-main>
</v-row>
</v-app>
</div>
</template>
By default, v-app has an internal wrapper with flex-direction: column CSS, meaning that its child elements are placed vertically. By wrapping these 2 child elements in a v-row, you place them in a wrapping element with flex-direction: row.
I guess you are misunderstanding the concepts. You are wrapping a v-navigation-drawer inside a navbar component.
In Vuetify v-navigation-drawer is a component used to build Sidebars and that's why your component is on vertical.
You should try to use v-app-bar instead. Here's the documentation: https://vuetifyjs.com/en/components/app-bars/
Edit 1
You can configure an app sidebar or an app navbar using the app option inside the component like that:
<v-navigation-drawer
app
>
...
</v-navigation-drawer>
Just like in the official documentation. If you do it that way, the component will work properly and your content will not be pushed down.

Vuetify: reserve space for scrollbars

I have a <v-navigation-drawer> which contains multiple <v-cards>. When clicking on a button, more cards appear and they overflow the screen; there's thus a scrollbar that appears. The problem is that this changes the width of the cards, which makes the transition look quite bad.
Is there a way to already reserve space for the scrollbar, or to overlay it on top of the card rather than making it change the width of the card?
I already tried playing with overflow-y, but haven't found any one working...
Before clicking on the button
After clicking on the button
Here is a sample code for my problem:
<template>
<div>
<v-navigation-drawer app left width="450" clipped>
<v-card>
<img src="https://pbs.twimg.com/profile_images/875996174305472512/upM71pVR.jpg" />
</v-card>
<v-card>
<v-btn #click="showImage = !showImage">Show Image</v-btn>
</v-card>
<v-card v-if="showImage">
<img src="https://i.pinimg.com/originals/5b/b4/8b/5bb48b07fa6e3840bb3afa2bc821b882.jpg" />
</v-card>
</v-navigation-drawer>
</div>
</template>
<script>
export default {
name: "TopBar",
data: () => ({
showImage: false
})
};
</script>

Vuetify overlay overlays the drawer

I'm trying to create a navbar for Vue application, I'm using Vuetify, on large screen there is toolbar, on small there is hamburger icon which opens the navigation drawer.
It works, but there is an overlay that comes in front of drawer and I can't change a page.
Here is the code:
<template>
<div>
<v-app-bar dark>
<v-app-bar-nav-icon class="hidden-md-and-up" #click="sidebar = !sidebar"></v-app-bar-nav-icon>
<v-navigation-drawer v-model="sidebar" app>
<v-list>
<v-list-item v-for="(item, i) in menuItems" exact :key="i" :to="item.path">{{item.title}}</v-list-item>
</v-list>
</v-navigation-drawer>
<v-toolbar-title>Jobify</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-btn text v-for="item in menuItems" :key="item.title">
<router-link :to="item.path">{{item.title}}</router-link>
</v-btn>
</v-toolbar-items>
</v-app-bar>
</div>
</template>
<script>
export default {
data: function() {
return {
sidebar: false,
menuItems: [
{ path: "/jobs", name: "jobs", title: "Jobs" },
{ path: "/companies", name: "companies", title: "Companies" },
{ path: "/jobs/new", name: "new-job", title: "Add job" }
]
};
}
};
</script>
<style>
</style>
Only Vuetify components that I'm using are here, there is, actually, v-app in App component.
Try to add hide-overlay prop to the v-navigation-drawer component in order to hide the overlay :
<v-navigation-drawer v-model="sidebar" app hide-overlay >

Categories

Resources