How to use object prop in Child component using Vue? - vue.js

I have a child component called Card.vue where I make a card based on the length of an object in the parent component. In the child component I would like to use the data inside the object send from the parent. I get the error message that 'legend' is not defined. How do I do solve this?
Parent component:
<alst-card v-for="(legend, index) in profile.legends.all" :key="index" v-bind="legend"></alst-card>
Child component:
<p class="card-text" style="min-width: 100px">{{ legend.data.kills.value }}</p>
export default {
props: {
legend: Object
}
}

Try v-bind:legend="legend" instead of v-bind="legend"
The legend on the left is the props that the child component declared, the legend on the right is the data/property from the parent.
For example if your children declared:
export default {
props: {
givemelegend: Object
}
}
Then in Parent.Vue, you would want: v-bind:givemelegend="legend"

Related

Data from props not showing in v-model (VueJS)

I'm trying to use a props from the parent component to use it as a data in my child component.
parent component :
<ChangeCommentModal :comment="this.modalInfo.comment" />
And child component (ChangeCommentModal) :
props: ['comment'],
data() {
return {
localComment: this.comment,
};
}
The localComment variable get the value but I can't use it in a v-model in this child component :
<textarea id="message" rows="2" v-model="localComment"></textarea>
The textarea is empty when the component is displayed.
Any idea ? Thanks !
Seems your code is only assign this.comment to localComment once when the child component is init. Instead, you can use watcher to watch the change of prop comment and assign it to the localComment everytime you update from the parent component. Let's try to see if resolve your problem
watch() {
comment(value) {
this.localComment = value
}
}

Calling function inside child component without an event?

Currently trying to use a method belonging to the parent
<p class="message-date text-center">
{{ $emit('format_date_day_month_year_time', message.date) }}
</p>
However I am getting the error.
Converting circular structure to JSON
--> starting at object with constructor 'Object'
How can I call a function inside a child component that does not rely on an event? I apologize for asking such a simple question but everything I was able to find on google is using $emit and using an event.
$emit was designed to only trigger an event on the current instance of vue. Therefore, it is not possible to receive data from another component this way.
For your case, I would suggest to use Mixins especially if you need to use certain functions among multiple vue components.
Alternately, let the child component call the the parent through $emit then receive the result from the parent through a prop.
Your code could be something as follows:
Child component
<template>
<p class="message-date text-center">
{{ date }}
</p>
</template>
<script>
export default {
name: 'Child',
props: {
date: String,
},
mounted() {
this.$emit("format-date", message.date);
},
}
</script>
Parent component
<template>
<Child :date="childDate" #format-date="formatChildDate" />
</template>
<script>
import Child from '#/components/Child';
export default {
components: {
Child,
},
data: () => ({
childDate: '',
}),
methods: {
formatChildDate(date) {
this.childDate = this.formatDateDayMonthYearTime(date)
},
formatDateDayMonthYearTime(date) {
//return the formatted date
},
},
}
</script>
with $emit you call a function where the Parent can listento.
where you are using it i would suggest a computed prop of the function.
But back to your Question here is a example of emiting and listen.
//Parent
<template>
<MyComponent #childFunction="doSomethingInParent($event)"/>
</template>
//Child
<template>
<button #click="emitStuff">
</template>
.....
methods:{
emitStuff(){
this.$emit(childFunction, somedata)
}
with the event you can give Data informations to a Parentcomponent.

Pass data from child to parent component with click event(data) in Vue

i need pass data (a slug) from a #click button to a function with $emit event, and then in the Parent component recive this and embebed in another component as a prop, to load a simple object.
This is my approach, but did not work
<-- Child Component (Conversaciones.vue) -->
<template v-slot:title>
<q-btn #click="SlugHijoPadre(conversacion.slug)">
{{ conversacion.contenido }}
</q-btn>
</template>
methods:{
SlugHijoPadre(Slugdata) {
this.$emit("enviar-conversacion", {
slug: Slugdata
})}}
<-- Parent Component -->
<Conversaciones #enviar-conversacion="slugConversacion"/>
components: {
Conversaciones,
Conversacion
},
data() {
return {
slugs: {}
};
},
methods: {
slugConversacion(slug){
this.slugs.push (slug);
console.log(slug);
}
},
//And finally pass a property to call an especific object of another component:
<Conversacion :slug="slugs"></Conversacion>
Check your slugs property, it's an object not an array so you can't use this.slugs.push. Change it to slugs: []

Vue.js child component not updated

I have 3 vue.js nested components: main, parent, child.
The parent component load basic data, the child is a simple countdown widget which needs just a data to be configured.
If I set the parent script with static data (IE deadline='2019-12-12') the child show the widget working nice, but if I use dynamic data it generate error.
I'm using computed to pass data to the child component and if I debug it using an alert I see 2 alerts: undefined and then the correct date.
The issue is the first computed data (undefined) crash the widget, so how to create child component using updated (loaded) data?
Parent template:
<template>
<div>
<flip-countdown :deadline=deadline></flip-countdown>
</div>
</template>
Parent Script: it needs to be fixed
export default {
components: {FlipCountdown},
props: ['event'],
computed: {
deadline: function () {
if (typeof(this.event.date)!="undefined") {
//alert(this.event.date)
return this.event.date;
} else {
return "2019-05-21 00:00:00";
}
},
},
Child template: it works
<template>
<div>
<flip-countdown :deadline="deadline"></flip-countdown>
</div>
</template>
Your parent component passes the deadline to its child component before the mounted lifecycle hook fires. Your child component sets its deadline with the initial value of undefined.
You should make deadline a computed property in child component:
computed: {
internalDeadline() {
return this.deadline; // comming from props
}
}
Then you can use internalDeadline in child.
Alternatively, you could wait to render the child component until deadline is defined:
<flip-countdown v-if="deadline !== undefined" :deadline="deadline"></flip-countdown>

Vue reactive component props

I have method in my component that adds popup and passing some props into its.
openPopup () {
this.$store.dispatch('addPopup', {
component: MapCropsPopup,
props: {
anchor: this.$refs.filter,
selectedCropIds: this.selectedCropIds,
activeSeason: this.activeSeason,
onBeforeClose: () => {
this.$router.push(this.getQuery({ showCrops: null }));
},
onSeasonChange: (season) => {
this.activeSeason = season;
}
}
});
}
Here, in child component i store all passed props into 'props' variable
props: ['props']
and use them directrly in template
<div class="mcp-seasons__btn"
:class="{ 'm--active': props.activeSeason === 'current' }"
#click="setActiveSeason('current')">
{{ i18n.CURRENT_LABEL }}</div>
To update current season in parent component I use method setActiveSeason
setActiveSeason (season) {
this.props.onSeasonChange(season);
}
it works good, and updates 'activeSeason' in parent component, but won't update same property in child component.
What should I do to make property reactive again?
When you do
selectedCropIds: this.selectedCropIds,
activeSeason: this.activeSeason,
you are making nonreactive members of an object that are initialized to the given values at the time. If, instead, you did something like
propParent: this
and in the popup component referred to props.propParent.activeSeason, you would be using the reactive item.