Vue.js v-if toggle for show/hide nav - vue.js

I am trying to make a nav that you can show/hide toggle by clicking on an button. Can anyone tell me what I am doing wrong here? I am still learning Vue so any help would be appreciated. Thanks.
Here's the code from navigation.vue:
<template>
<div>
<nav v-if="seen">
<ul>
<li>front</li>
<li>contact</li>
</ul>
</nav>
<p><button v-on:click="seen = !seen">Toggle</button></p>
</div>
</template>
<script>
export default {
data: {
seen: true
}
}
</script>
Importing the navigation in App.vue:
<template>
<main>
<app-navigation></app-navigation>
<app-front></app-front>
<app-footer></app-footer>
</main>
</template>
<script>
import Navigation from './components/navigation.vue'
import Front from './components/front.vue'
import Footer from './components/footer.vue'
export default {
components: {
'app-navigation': Navigation,
'app-front': Front,
'app-footer': Footer
},
data () {
return {
}
}
}
</script>

With components, your data property needs to be a function.
data(){
return {
seen: true
}
}

Related

Vue Material Modal in Child Component is not showing when child component is imported to a parent component

I am having trouble in displaying the modal from a child component when I imported it into the parent component as tab content.
So first, the parent component looks something like this:
parent.vue
<template>
<div>
<nav-tabs-card no-label tabs-plain>
<template slot = "content">
<md-tabs>
<md-tab id="child" label="Child Component">
<child-component/>
</md-tab>
</md-tabs>
</template>
</nav-tabs-card>
</div>
</template>
<script>
import {NavTabsCard} from '#/components';
import childComponent from '../child-component.vue';
export default {
components: {
NavTabsCard,
"child-component": childComponent
}
}
</script>
then child-component.vue
<template>
<div>
<md-button #click = "myModalShow">
</md-button>
<modal v-if="myModal" #close = "myModalHide"/>
</div>
</template>
<script>
import {Modal} from '#/components';
export default {
components: {
Modal
},
data() {
return {
myModal: false
};
},
methods: {
myModalShow() {
this.myModal = true
console.log("Modal is visible");
},
myModalHide() {
this.myModal = false;
console.log("Modal is hidden.");
}
}
}
</script>
When I click the button to display the modal, the console.log returns that the myModal value is true, but the modal is not shown at all. I also tried to increase the modal's z-index but it does not work too.

Vue - Unable pass specific value to higher component

I am getting the following - Cannot read property 'free' of undefined.
I will be adding this button component on multiple pages and I have data object which will allow me to add text based on whatever page I want displayed on a page. For example if its on the homepage I would like to use <buttons :text="buttonText.free" /> and on about us page I would like to use <buttons :text="buttonText.spend" />
Template file
<template>
<main class="container">
<buttons :text="buttonText.free" />
</main>
</template>
<script>
import Buttons from '~/components/atoms/buttons.vue'
export default {
components: {
Buttons
}
}
</script>
Component file
<template>
<div>
<button class="button"">
<span>{{ buttonText }}</span>
</button>
</div>
</template>
<script>
export default {
props: {
text: String
},
data () {
return {
buttonText: {
free: 'free',
spend: 'spend',
now: 'now',
nowFree: 'now free'
}
}
}
}
</script>
Could you tell me what I am doing wrong?
You should define your data in your parent component's data property. All the variables that is used inside the template tag will be fetched from data, computed or props of the component. You are passing an undefined buttonText data to your buttons component.
<template>
<main class="container">
<buttons :text="buttonText.free" />
</main>
</template>
<script>
import Buttons from '~/components/atoms/buttons.vue'
export default {
data() {
return {
buttonText: {
free: 'free',
spend: 'spend',
now: 'now',
nowFree: 'now free'
}
}
},
components: {
Buttons
}
}
</script>
and in your buttons component, just accept the props passed by the parent component. In this case, you are using text as the props of the buttons component.
<template>
<div>
<button class="button"">
<span>{{ text }}</span>
</button>
</div>
</template>
<script>
export default {
props: {
text: String
}
}
</script>
template.vue
<template>
<main class="container">
<buttons :text="your customized text" />
</main>
</template>
<script>
import Buttons from '~/components/atoms/buttons.vue'
export default {
components: {
Buttons
}
}
</script>
buttons.vue
<template>
<div>
<button class="button">
<span>{{ text }}</span>
</button>
</div>
</template>
<script>
export default {
props: {
text: String
}
}
</script>
here is a simple solution to solve your problem
but you need to learn more fundamentals on vue components
vue component doc

Why won't vue.js update the DOM?

Working my way learning about Vue. I chose it as the better alternative after looking at React, Angular and Svelte.
I have a simple example that its not working probably because I'm not getting/understanding the reactive behaviour of Vue.
Plain simple App:
<template>
<div id="app">
<app-header></app-header>
<router-view />
<app-footer></app-footer>
</div>
</template>
<script>
import Header from './components/Header.vue'
import Home from './components/Home.vue'
import Footer from './components/Footer.vue'
export default {
components: {
name: 'App',
'app-header': Header,
'app-footer': Footer
}
}
</script>
Where Home.vue and Footer.vue have plain HTML content on the template.
On Header.vue I have:
<template>
<div>
<h1>The Header</h1>
<nav>
<ul>
<li>Curr Player: {{ ethaccount }}</li>
<li>Prop owner: {{ propOwner }}</li>
</ul>
</nav>
<hr />
</div>
</template>
<script>
export default {
data() {
return {
ethaccount: 'N/A',
propOwner: 'N/A'
}
},
methods: {
update() {
var ethaccount = '0xAAAAAA123456789123456789123456789'
console.log('ETH Account: ' + ethaccount)
var propOwner = '0xPPPPPPPPPPP987654321987654321'
console.log('Prop Account: ' + propOwner)
}
},
mounted() {
this.update()
}
}
</script>
But I'm unable to get the header updated and unable to find what I'm doing wrong. Help.
If you need to read a little bit more about the reactivity of the datas in vuejs check this link : https://v2.vuejs.org/v2/guide/reactivity.html
If you need to access/change your data try to do it like that :
this.$data.ethaccount = 'foo';
this.$data.propOwner = 'bar';
For me the problem is taht you re-declare your variable locally by doing :
var ethaccount = "0xAA...";
By doing such you never change the value of the data you're accessing through your template.
Hope it will solve your problem.

How to get $auth value in component outside of registered vue-router component

I have a layout theme/default which has vue-router inside like this
<template>
<div id="app">
<component :is = "layout">
<router-view></router-view>
</component>
</div>
</template>
<script>
const default_layout = "theme";
export default {
computed: {
layout(){
return ( this.$route.meta.layout || default_layout) + '-layout';
}
},
};
</script>
And then the theme layout is like this:
<template>
<div class="app-home">
<nav-bar/>
<div class="container-fluid section">
<div class="left-fixed">
<side-bar/>
</div>
<div class="right-card">
<slot />
</div>
</div>
</div>
</template>
<script>
import NavBar from './Navbar'
import SideBar from './Sidebar'
export default {
data() {
return {
}
},
mounted(){
},
components: {
NavBar,
SideBar
}
}
</script>
Now I have to pass current auth user in Navbar and Sidebar for logout and current user role which can be obtained from vue-auth $auth but only inside router component. Can anybody help it to fix this.
Using vuex I had made a state which I call as computed property and I set whenever User logged in.

How to access parents data value in vuejs with the template syntax

In my VueJS app I am using bootstrap-vue and want to use iframe inside a collapsable elements b-collapse. Because of some problems with iframe content and resizing (problem not related here) I found out that if I enable/disable b-embed with conditional rendering it works.
The parent component b-collapse has a data element called show which change its state if toggle is clicked. In my HelloWorld component I want that b-collapse can pass it's show value into the if check of b-embed.
My approach with this.$parent.$data.show isn't working and I am not sure if there is any better way to do so.
<template>
<div>
<b-btn v-b-toggle.logs>
<span class="when-opened">Close</span>
<span class="when-closed">Open</span>
Trace
</b-btn>
<b-collapse id="logs">
<b-embed :src="src" v-if="this.$parent.$data.show"></b-embed>
<div>Data: {{this.$parent.$data.show}}</div>
</b-collapse>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Prop, Component, Inject } from "vue-property-decorator";
#Component
export default class HelloWorld extends Vue {
src = "http://localhost:7681/";
}
</script>
Like this:
parent.vue
<template>
<Child :show="myShow"></Child>
</template>
<script>
import Child from './child'
export default {
data () {
return {
myShow: 'StackOverflow'
}
},
components: {Child}
}
</script>
child.vue
<div>
<b-btn v-b-toggle.logs>
<span class="when-opened">Close</span>
<span class="when-closed">Open</span>
Trace
</b-btn>
<b-collapse id="logs">
<b-embed :src="src" v-if="this.$parent.$data.show"></b-embed>
<div>Data: {{this.$parent.$data.show}}</div>
</b-collapse>
</div>
<script>
export default {
props: {
show: {
type: Number,
require: true
}
}
}
</script>
Or use vuex to do this.