In my App.vue component I have a Navigation Drawer menu with main items and some subitems. These subitems should be shown only after some event (button click) on the child component's page (variable totalResult should be true):
<v-list-item
v-show="totalResult"
#click="$vuetify.goTo('#somelink')">
<v-list-item-content>
<v-list-item-title>Review</v-list-item-title>
</v-list-item-content>
</v-list-item>
But this child component is not directly connected to the App.vue component and I don't know how to pass a prop to this App.vue.
Is there a way to toggle this submenu items on and off from outside?
Use vuex in < vue2.7, or a reactive value in vue2.7+. Either way, you declare reactive state in one file, then import that value into your other files.
Here is the general idea:
mystate.js
const showSidebar = ref(false)
export showSidebar
toggle button
<script setup>
import {showSidebar} from './mystate'
</script>
<template>
<button #click='showSidebar=!showSidebar />
</template>
sidebar parent
<script setup>
import {showSidebar} from './mystate'
</script>
<template>
<sidebar :value='showSidebar' />
</template>
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 have a component with two buttons, each with an unique function:
<template>
<v-container>
<v - button ref = "button" / >
<v - button ref = "buttons" / >
</v-container>
</template>
How I want to address both buttons in the parent and apply my two functions, I have written in the parent, on them.
<Button #click="refer to the two buttons" />
...
<script>
methodOne(){
console.log("A")
}
methodTwo() {
console.log("B")
}
</script>
I just don't know how do that correctly. Short: having multiple buttons in the child component and multiple functions in the parent component who should be triggered when the buttons in the child component are triggered.
you can use Vue $emit function inside a child component. So:
Your child component
<template>
<div>
<button #click="$emit('aButttonClick')">Button A</button>
<button #click="$emit('bButttonClick')">Button B</button>
</div>
</template>
your parent component
<ButtonComponent #aButttonClick="methodOne" #bButttonClick="methodTwo" />
...
<script>
methodOne(){
console.log("A")
}
methodTwo() {
console.log("B")
}
</script>
And you can use emit function inside a function. And you can add additional params to.
See here https://v2.vuejs.org/v2/guide/components.html
I'm trying to build my portfolio using Vue and Vue Router. What I'm trying to do is have a link in my navbar and when you click it, it will scroll down to that section. I have all my sections in separate components so I can't figure out how to make the scroll behaver function for everything. I have one Home.vue, and that component is the main component and all other components are included inside Home.vue.
Home.vue
<template>
<div class="home">
<HeaderSection />
<AboutSection />
<SkillsSection />
<TimelineSection />
<PortfolioSection />
<TestimonialsSection />
<ContactSection />
</div>
</template>
<script>
// # is an alias to /src
import HeaderSection from "#/components/HeaderSection.vue";
import AboutSection from "#/components/AboutSection.vue";
import SkillsSection from "#/components/SkillsSection.vue";
import TimelineSection from "#/components/TimelineSection.vue";
import PortfolioSection from "#/components/PortfolioSection.vue";
import TestimonialsSection from "#/components/TestimonialsSection.vue";
import ContactSection from "#/components/ContactSection.vue";
export default {
name: "Home",
components: {
HeaderSection,
AboutSection,
SkillsSection,
TimelineSection,
PortfolioSection,
TestimonialsSection,
ContactSection,
},
};
I just found a solution to this. in my Navbar i have an anchor tag <v-btn depressed plain text color="white"> Portfolio </v-btn> that points to the specific id in that component I want to move to <div id="portfolio"></div>. You can also make is scroll smoothly with document.querySelector(element).scrollIntoView({ behavior: "smooth" });
This is the structure of my vuejs application.
<template>
<div class="page-body-wrapper">
<Sidebar/>
<div class="main-panel">
<Header/>
<div class="content-wrapper">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import Header from '../header/header';
import Sidebar from '../sidebar/sidebar';
export default {
name: 'Layout',
components: {
Header,
Sidebar
}
}
</script>
In all the routes that are rendered inside <router-view>, i am calling various functions and api calls based on a store variable 'myValue'. And, I have a dropdown in my <Header/> component ( which is common for all routes). Whenever I select a value from the dropdown in header, the store variable 'myValue' changes. Now, I need to remount whatever component is rendered inside <router-view> whenever the store variable 'myValue' changes. Using watch will be a last option since I will have to do the same in a number of components. I cannot use computed, since I have to fetch all data in either 'created' or 'mounted' hook. Is there any option to remount the entire <router-view> when a store variable changes? Note: I am using vuex for state management.
Just pass a key to <router-view :key="myValue"></router-view>, or in your case <router-view :key="$store.state.myValue"></router-view>.
Also check out this answer.
I'm creating single file components in Vue2, and I'm including a child component:
Parent Component:
<template>
<div>
<my-component-2>
</my-component-2>
</div>
</template>
<script>
....
</script>
Child component (my-component-2):
<template>
<my-component-3>
</my-component-3>
</template>
<script>
....
</script>
Grandchild component (my-component-3):
<template>
<div v-for="(item, index) in items">
</div>
</template>
<script>
...
</script>
But my-component-3 is not "rendered", however if I wrap <my-component-3> in a div (like in the parent component calling my-component-2), then it works.
Is there a way to call a child component without wrapping it in any html tag?
The <template> of a component can only have one direct child node.
Since your my-component-3 component's root element used a v-for, it could not render, since it would have multiple child nodes.
You never need to wrap a component in any element when using it in another component's template.
Example Multiple Elements
<template>
<template v-if="anyKey">
<div> DIV 1 Content </div>
<div> DIV 2 Content </div>
</template>
</template>
export default {
name: 'MyComponent',
data() {
return {
anyKey: "Any Value"
}
},
// ...
}
HTML will render without wrapping element
<div> DIV 1 Content </div>
<div> DIV 2 Content </div>