1- Intro
Vuejs Provides Props as custom attributes you can use to pass data to a child component.
With these props, we can customize our component however we want.
2- how to pass props to a component “not nested”?
Vue.component('child', { props: ['myprop'], #registering our prop 'myprop' template: ` <div class="person-card"> <h2>{{ person.name }}</h3> <h4>{{ person.age }}</h4> <img :src="person.image"/> </div> ` })
Now in our app.vue
we define some an object ‘person
’ which we want to pass to our Child : Component:
new Vue({ el: "#app", data: { persons:{ name: Alex, age: 19, image: 'https://.../image.jpg' } } })
finally, you only bind the object ‘person’ to our prop
<child :myprop="person"><child>
3- How to watch props “not nested”?
For the same example above ↑
We can easily watch changes in our prop.
to notice the changes we need to define another property ‘propChanged’ besides persons.
new Vue({ el: "#app", data: { persons:{ name: Alex, age: 19, image: 'https://.../image.jpg' }, propChanged: false ///when prop changes this becomes true } })
To the same file, we must add a Watcher to watch changes of our prop:
new Vue({ el: "#app", data: { persons:{ name: Alex, age: 19, image: 'https://.../image.jpg' }, propChanged: false ///when prop changes this becomes true }, watch: { yourProp (val, oldVal) { if (val !== oldVal) this.propChanged = true } } })
Now in case our prop changes, the condition above if (val !== oldVal)
is valid, therefore propChanged changes its value to true.
3- How to Pass Nested props?
Problem: In Vuejs, it is possible to have an object as a Prop. But, how to watch all properties when we have deeply nested Props?
Example of nested props:
props: { nestedProps: { // nested object. fullName: { firstName: { type: String, required: true }, lastName: { type: String, required: true } }, otherValue: { birth: { type: Number, required: true age: { type: Number, required: true default: 16 // if age was not provided } }, }
Note: You can ensure your component receives exactly the data want by specifying:
- type: you can specify the type of what you component is going to receive.
{type: string | number | constructor | …}
Example:propA: Number, // inline defintion propD: { // object definition type: Number, default: 100 },
"default": you can give a Default value to your prop in case no value was passed.
{type: string | number | function | …}
Example:propE: { type: Object, default: function () { return { message: 'hello' } } }
"required": you can specify if the value is required or not.
Example:propC: { type: String, required: true }
"validator": you can validate and filter your data however you want using the option which accepts a function.
Example:propF: { validator: function (value) { // The value must match one of these strings return ['success', 'warning', 'danger'].indexOf(value) !== -1 } }
Defining our Child component:
Vue.component('child', { props: ['nestedProps'], #registering our prop 'myprop' template: ` <div class="person-card"> full name is: <h2>{{ nestedProps.fullName.firstName }}</h2> <h2>{{ nestedProps.fullName.lastName }}</h2> birth and age are: birth: <p>nestedProps.otherValues.birth</p> age: <p>nestedProps.otherValue.age</p> </div> ` })
Now we can define the Data object that we want to render:
myNestedData: { fullName: { firstName: { 'Alex' }, lastName: { 'Wayne' } }, otherValue: { birth: { 1999 } age: { 20 } }, }
Now, in our child component, we bind our prop with the data object we want like this:
<child :nesttedProps="myNestedData"><child>
4- How to Watch Nested props?
it is very simple, for the same example we can do this:
watch: { myNestedData { handler(newValue, oldValue) { // react to changes }, deep: true } }
using deep: true in vue.js allows you to keep track of all root and child elements of your specified property.
Notes:
- When you got more Data values (e.g: persons ).
Just use an array to store your data list of persons and their info, then, simply use the v-for Directive to easily render your List.
note: when your app gets complicated and hard to understand consider this Topic:
What Is Vuex And How Does It Work? or check this one for all known techniques: How to pass data between Vuejs components effectively?
<template> <div> <child v-for="(item, key, index) in myDataArray" :item="item" :index="index" :key="key""> </child> </div> </template>
data(){ return { myDataArray: [ { // person 1 fullName: { {firstName: Alex}, {lastName: Wayne} }, otherValues: { {age: 15}, {birth: 2005} } }, // person 2 { fullName: { {firstName: Alex}, {lastName: Wayne} }, otherValues: { {age: 15}, {birth: 2005} } } ] },
finally you must change your child component to be compliant with your array’s data.
Vue.component('child', { props: ['nestedProps'], #registering our prop 'myprop' template: ` <div class="person-card"> full name is: <h2>{{ myDataArray.fullName.firstName }}</h2> <h2>{{ myDataArray.fullName.lastName }}</h2> birth and age are: birth: <p>myDataArray.otherValues.birth</p> age: <p>myDataArray.otherValue.age</p> </div> ` })
see also:
→ for an easier way to communicate between components: What Is Vuex And How Does It Work?
→for all the techniques see: How to pass data between Vuejs components effectively?
And that’s it hope you enjoyed this tutorial!
cheers