How to pass layout property to page component in nuxtjs - vue.js

I am completely new to VueJS and NuxtJS. I can't seem to pass a property in the layout to a page component.
This is my layouts/default.vue
<template>
<Nuxt myprop="hello world" />
</template>
<script>
export default {
data: () => ({
myprop: 'hello galaxy',
}),
}
</script>
This is my pages/index.vue
<template>
<div>My Prop is: {{myprop}}</div>
</template>
<script>
export default {
props: {
myprop: {
type: String
},
},
}
</script>
When I load up my app, I expect to see My Prop is: hello world. But instead, I see My Prop is:, and it seems myprop is empty.
What am I doing wrong? How does a layout component pass a property to child component in VueJS or NuxtJS?

You cannot pass props in that way, but you could use provide/inject pattern to pass the data from layout to the page :
layout/default.vue
<template>
<Nuxt />
</template>
<script>
export default {
provide: function () {
return { myprop: this.myprop };
},
data: () => ({
myprop: 'hello galaxy',
}),
}
</script>
pages/index.vue
<template>
<div>My Prop is: {{myprop}}</div>
</template>
<script>
export default {
inject: ["myprop"],
}
</script>

Related

How to pass vmodel property to child component in nuxjs

I can't seem to pass dynamically modified properties from layouts into the <Nuxt /> component.
This is my ~/layouts/default.vue
<template>
<div>
<input v-model="myprop" />
<span>{{myprop}}</span>
<Nuxt />
</div>
</template>
<script>
export default {
provide: function () {
return {myprop: this.myprop};
},
data: () => ({
myprop: 'hello galaxy',
}),
}
</script>
This is my ~/pages/index.vue
<template>
<div>My Prop is: {{myprop}}</div>
</template>
<script>
export default {
inject: ["myprop"]
}
</script>
On the web page I see hello galaxy printed 3 times, once in the input, once in a span, and once in the Nuxt component. But when I edit the input field, only the span is updated. The Nuxt component does not capture the changes in myprop. The Nuxt component continues to show only hello galaxy while put the input and span shows changes as I type on my keyboard
What am I doing wrong?
The provide/inject is useful for simple situation, but if you've some reactive stuff the vuex store is more convenient :
in store/index.js
add a state called search and its mutations and actions :
export const state=()=>({
search:''
})
export const mutations ={
SET_SEARCH(state,payload){
state.search=payload
}
}
export const actions ={
setSearch(context,payload){
context.commit('SET_SEARCH',payload) ​
}
}
in layout/default.vue add computed property with setter/getter bound to the store:
<template>
<div>
<input v-model="search" />
<span>{{search}}</span>
<Nuxt />
</div>
</template>
<script>
export default {
computed:{
search:{
get(){
return this.$store.state.search
},
set(val){
this.$store.dispatch('setSearch',val)
}
}
}
}
</script>
in pages/index.vue :
<template>
<div>My search is: {{search}}</div>
</template>
<script>
export default {
computed:{
search(){
return this.$store.state.search
}
}
}
</script>

Vue: computed property in parent not called

In Vue 3 i have a problem calling a computed property. I need to show a component if a user sign in correctly.
In my App.vue i have:
<template>
<div class="wrapper">
<Sidebar v-if="authorized"/>
</div>
<main class="content">
<router-view />
</main>
</template>
<script>
import Sidebar from "#/components/Sidebar.vue";
export default {
name: "App",
components: {
Sidebar
},
computed: {
authorized: () => {
//some code
}
},
};
For example, when i go to /login path, the authorized computed property is called.
Then, in my Login.vue component, i have a method with:
this.$router.push({ name: 'Dashboard' })
The problem is that after the router.push, the computed property in App vue parent isn't called.
Why?

Vuej.s: How pass variable to component attribute

How can i pass variable to component in Vue.js (not via props)? Is that possible?
Here app.js:
import PlayingField from '../app/components/PlayingField'
import GameConfig from '../../gameConfig'
new Vue({
el: '#app',
components: {
playingfield: PlayingField,
},
data: {
gameConfig: GameConfig
}
});
In game config is json and there is key 'maxUniqueCards' and this value i want in component playingField... No in template but in attribute to next work with it... (generate cards, order.... just for usage in playingField component methods...)
You can use the $parent property:
<template>
<div>
App
<input type="text" v-model="propTest">
<Child />
</div>
</template>
<script>
import Child from '#/components/Child.vue';
export default {
name: 'App',
components: { Child },
data: () => ({
propTest: 'abc',
}),
};
</script>
<template>
<div>
child
<button #click="test">Test</button>
</div>
</template>
<script>
export default {
name: 'Child',
methods: {
test() {
console.log(this.$parent.propTest);
},
},
};
</script>
Be careful with this property, you must use in edge cases: https://v2.vuejs.org/v2/guide/components-edge-cases.html#Accessing-the-Parent-Component-Instance

Vue-cli change object value globally

I have this code in file app.vue :
<template>
<div id="app">
<button v-on:click="component = 'login'">aa</button>
<component v-bind:is="component"></component>
</div>
</template>
<script>
import acceuil from './components/acceuil.vue'
import login from './components/login.vue'
export default {
name: 'app',
components: {
acceuil,
login
},
data(){
return {
component: 'acceuil'
}
}
}
</script>
How can I toggle between acceuil/login in component from a different vue file ?
You need to pass the imported dependency (the object or the name of the component as a string) to v-bind:is. You can do this by returning it in a computed function and pass it to a computed property, which you then can use in the template.
<template>
<div id="app">
<button v-on:click="isLogin = true">Show Login</button>
<component v-bind:is="currentComponent"></component>
</div>
</template>
<script>
import acceuil from './components/acceuil.vue';
import login from './components/login.vue';
export default {
name: 'app',
data () {
return {
isLogin: false
};
},
computed: {
currentComponent () {
return this.isLogin ? login : acceuil;
}
},
};
</script>
See also the documentation of dynamic components in the official docs.

How to bind a prop value using a function and pass it to another component

Is it possible to bind a prop to a function?
In my example below I’m trying to get a value from a function in the main App.vue and pass it as a prop to the child component customComponent.
e.g. (this example doesn’t work)
App.vue
import customComponent from ‘./custom-component.vue'
<template>
<custom-component
v-bind:myValue="geMyValue()"
></custom-component>
</template>
<script>
export default {
name: "Item",
methods: {
getMyValue: function() {
return 1+3;
}
}
}
</script>
customComponent.vue
<template>
<h3 class="some-custom-layout">custom component</h3>
<input type="button" #click="sendMyValue()" />
</template>
<script>
export default {
name: “custom",
props: ['myValue']
methods: {
sendMyValue: function() {
console.log(this.myValue);
}
}
}
</script>
It's possible, but probably it would be better to use computed properties, if you are going to return value:
<template>
<custom-component
v-bind:myValue="myValue"
></custom-component>
</template>
<script>
export default {
name: "Item",
computed: {
myValue: function() {
return 1+3;
}
}
}
</script>
https://v2.vuejs.org/v2/guide/computed.html