How pass data from parent to child in NuxtJS - vue.js

i wonder how passing some string or dynamic data from parent to child in NuxtJs
how i tried it and not worked:
it's my parent component:
<template>
<div>
<ChildComponent :someData="Some String" />
</div>
</template>
<script>
import ChildComponent from "~/components/childComponent.vue";
export default {
components: {
ChildComponent,
},
}
</script>
and here is my ChildComponent
<template>
<div>
{{someData}}
</div>
</template>
<script>
export default {
name:"ChildComponent",
props: {
someData: String
}
}
</script>
and this method nothing rendered in ChildComponent

You don't have to bind if you are passing values directly, ie, no need of semicolon.
<ChildComponent someData="Some String" />
You only need to bind if you are passing data.
<template>
<div>
<ChildComponent :someData="localData" />
</div>
</template>
<script>
import ChildComponent from "~/components/childComponent.vue";
export default {
components: {
ChildComponent,
},
data(){
return {
localData: "Some String"
}
}
}
</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 - 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

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 get refs element in scoped slot

If there are some refs in slot's template, how can I access these refs from the component? For example:
v-component.vue
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
created() {
console.log(this.$refs.ele)
}
}
</script>
app.vue
<template>
<v-component>
<template slot-scope="props">
<h1 ref="ele"></h1>
</template>
</v-component>
</template>
<script>
import VComponent from './v-component
export default {
components: { VComponent }
}
</script>
this.$refs.ele in v-compoent.vue output undefined. My question is how can I get this element?
Each element in named slot and scopedSlot has context.$refs.
Do not forget to check if object exists first.
<template>
<v-component>
<template slot-scope="props">
<h1 ref="ele">{{ props }}</h1>
</template>
</v-component>
</template>
<script>
import VComponent from './v-component'
export default {
components: { VComponent }
}
</script>
and
<template>
<div>
<slot demo="foo"></slot>
</div>
</template>
<script>
export default {
created() {
this.$nextTick(function() { // lazy
console.warn(this.$scopedSlots.default()[0].context.$refs)
});
}
}
</script>
Result:
This is considered as a bad idea by Vue developers: https://github.com/vuejs/vue/issues/7661
Btw, in my case in Vue3, the el entries of my slots retrieved by
this.$refs.myRef.$slots['my-slot']().el
is always null (as appContext)
On Vue 2 you can do this on mounted
mounted() {
console.log(this.$slots)
},
with more precision
You can do this
mounted() {
console.log(this.$slots.name_of_your_slot)
},

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