Vue - Emit Child to parent - vuejs2

In a vue2 application i need to send a value from a child to the parent. I try something like this
Child function
goTo(id: string) {
this.$emit('goToSpots', id)
},
Parent Component
<Main
class="px-5"
#goToSpots="goToSpots()"
/>
Parent function
goToSpots(id: string) {
this.selected = id
},
The problem: this.selected returns undefined, can't get param properly.
The question is: Whats is the proper way to send params?

In your HTML template, use
#goToSpots="goToSpots($event)"
or
#goToSpots="goToSpots"
instead. At the moment, you are not passing any argument to the function. If you don't add brackets at all, the parameter is automatically added and if you use brackets, you can pass the reserved variable $event which contains the emitted data.

Related

VueJS Use VNode inside render function with createElement?

I am trying to render a Vnode inside my render function. In such a way that I can still give that element children.
I know you can have an array of Vnodes as the third argument of createElement(tag, data, vnode[]) but since I want to give this specific Vnode children still I seem to be a little stuck,
I have tried doing something like:
const vnodeObj = {tag: vnode.tag, data: vnode.data}
//Skip to inside render function
createElement(vnodeObj.tag, vnodeObj.data, []).
Which worked well to create the tag but I have found that the data object returend from Vnode.data is not the same for the data object createElement expect for example:
If I were to add a class "test" and a ref "test2" to a element using create element the data object would look like so:
{
attrs: { class: "test", ref: "test2"},
}
while the Vnode.data would return something like:
{
"ref":"test2",
"staticClass":"test"
}
Leading me to believe there must be a better way to render a single Vnode and its data and continue giving it children with createElement.

Emitting object or value in vue.js component child to parent communication

I would like to know which is better way to emit data to parent in vue component. From parent to child I pass prop object but from child to parent with $emit. Should I pass object or value? e.g.: { product } or product.id and also I have to reuse some data in the { product } like product.price on event listener. What should I use? Emit an object or just value then loop and condition in listener function?
Just use a two way sync here:
#product.sync="product"
In the child:
this.$emit('update:product', product)
Whenever you make a change to the property of the product.
This does not work in case of Pass by reference. I mean it works but Vue is screaming don't mutate props directly...
Where movie is an object and genres is an array. Child components props and event
props: {
genres: {
type: Array,
default () {
return []
}
}
}
...
this.$emit('changeGenreList', this.genres)
I had to make the local copy of this array with slice() and then I was emitting this copy.

vuejs ref property has no effect when using with createElement

I've written a custom render function for a Vue Component, but when I set the "ref" property in the data object that is passed to the createElement function, nothing shows up in the $refs of the root vm (VueComponent)
Vue.component('sm-form-row', {
render: function (createElement) {
// Create the Row Div and append the columns
return createElement('div', {
class: {
'row': true
},
ref: 'some computed value'
});
}
});
What am I missing, the class is being applied correctly but the $refs keep showing empty.
The ref is beign applied and i made a fiddle to see it that it works.
But,if you want to add a reference to sm-form-row component then you have to add the ref attribute in the parent component.For example in parent component:
<sm-form-row ref="formRow" />
And in your parent component you can access it as:
this.$refs.formRow
Also you will be able to access the methods of the child component.For example if the child component has a method called myMethod you can access it in parent component like this:
this.$refs.formRow.myMethod

How to define property types when passing props to grandchildren in Vue.js?

I have a Vue component foo inside my HTML and I pass a parameter to it like this:
<foo some="Some String"></foo>
Now inside the foo component I define the property type and default value like so:
export default {
name: "foo",
props: {
some: {
type: String,
default() { return '' }
}
}
}
The foo component's template has another component bar which I pass the some property: <bar :some="some"></bar>.
Now my question is: do I need to again define the type and default value for the some property, this time inside the bar component? So basically copy the props code from the foo component and paste it into the bar component or is there another way?
foo has ensured the type and default value, so there is no need to validate them in bar. If the type were something that has special behavior (e.g., boolean), you would need to specify it, but there's nothing special about string.
Every component instance has its own isolated scope. This means you cannot (and should not) directly reference parent data in a child component’s template. Data can be passed down to child components using props.
Passing data with props
What you need here is to use scoped slot:
Scoped slots allows you to pass props down from Parent components to Child components without coupling them together.

Pass Function as Property to Vue Component

I am trying to make my Vue Component reusable but there is a part in it which requires to run a function on button click which I have defined in the parent component.
The component's button will always run a parent function and the parameter it passes is always the same (its only other property).
Right now I am passing 2 properties to the component: 1) an object and 2) the parent function reference, which requires the object from 1) as a parameter.
The Child-Component looks like this (stripped unnecessary code):
<button v-on:click="parentMethod(placement)">Analyze</button>
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.method(placement);
}
}
});
The parent is making use of the child like this:
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
methods: {
analyzePlacement: function(placement) {
this.active_placement = placement;
},
}
As you can see, the child has only one property, placement, and the callback reference. The placement must be put in as a parameter to the reference function from the parent.
But since the parent defines the parameters, the child shouldn't concern itself with what it needs to pass to the parent function. Instead I would prefer to already pass the parameter along in the parent.
So instead of
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
I would prefer
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement(placement)"></reporting-placement>
(including appropriate changes in the child).
But passing the parameter along does not work that way.
Is it possible (maybe in other syntax) to 'bind' the variable to the function reference so that it is automatically passed along when the callback is called?
Info: I don't get an error message if I write it down as above but the whole Vue screws up when I pass the parameter along to the component.
Hope the issue is clear :-) Thanks a lot!
By reading your proposal I've found out that you are overusing the props passing.
Your concern that child component should not have any knowledge about the way that the parent component uses the data is completely acceptable.
To achieve this you can use Vue's event broadcasting system instead of passing the method as props.
So your code will become something like this:
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.$emit('reporting-placement-change', placement)
}
}
});
And you can use it like this:
<reporting-placement v-bind:placement="placement" #reporting-placement-change="analyzePlacement($event)"></reporting-placement>
But if you need the data which is provided by the method from parent it's better to consider using a state management system (which can be a simple EventBus or event the more complex Vuex)
And finally, if you really like/have to pass the method as a prop, You can put it in an object, and pass that object as prop.