CodeOrc.com - Learn by example
X
Make an RPG
Vue Implementations

Vue what do props do

attributes are the meta data strings in between the brackets of a tag.

In the following tag, my_name="Jim" is an attribute.

<intro myName="Jim"></intro>

props let you pass attributes into your component to be used in the template.

Vue.component('intro', { template: `<div> Hello {{ myName }} </div>`, props: ['myName'] }); var app = new Vue({ el: '#demo' });
DO IT
Change the name from Jim to Bob.
Add your own properties: age, birthday, etc.

Variable Naming

HTML is not case sensitive, so your uppercase HTML code will become lowercase. Javascript won't allow dashes in your variable names, so you can't use "my-name".

The most accepted standard in vue is to use kebab-case in HTML (my-name), and camelCase in Javascript: (myName).

Alternatively, you can separate words by underscores (my_name) in both HTML and Javascript that way it's consistent.

Dynamic Prop

Currently our name is hard coded in the tag as "Jim". Now, let's make that dynamic based on some variable that we can change. The name of the variable is "character"

Notice the v-bind, that's key to making it dynamic.

<div id="demo"> <intro v-bind:person="character"> </intro> </div>
Vue.component('intro', { template: `<div> Hello {{ person }} </div>`, props: ['person'] }); var app = new Vue({ el: '#demo', data: { character: 'Desmond' } });
DO IT
Remove the v-bind: from the HTML and rerun it.

The "character" variable is on the parent vue instance, not inside the Vue component.


You can set dynamic properties with any data type

<div id="demo"> <intro v-bind:isAlive="true" v-bind:hasItems="['shield', 'sword'] v-bind:gold="27"> </intro> </div>

Pass an Object

You don't have to pass each parameter with it's own attribute. You can pass entire objects in one attribute.

<div id="demo"> <intro v-bind:person="character"> </intro> </div>
Vue.component('intro', { template: `<div> Hello {{ person.name }} </div>`, props: ['person'] }); var app = new Vue({ el: '#demo', data: { character: { name: 'Mike' } } });
DO IT
Add some of your own character attributes: XP, HP, Level, etc.

One-way Data flow

When parent values are changed, the props that are passed down to child components will get updated, as in the example below. When you click on the button, it changes the character name in the parent and automatically gets propogated down.

<div id="demo"> <intro v-bind:person="character"> </intro> </div>
Vue.component('intro', { template: `<div> Hello {{ person.name }} </div>`, props: ['person'] }); var app = new Vue({ el: '#demo', data: { character: { name: 'Mike' } } });
DO IT
Add some of your own character attributes: XP, HP, Level, etc.

props are propogated down. But, if they change in the child, they are not propogated up. This makes the code easier to understand and prevents accidentally modifying the parent's value.

"every time the parent component is updated, all props in the child component will be refreshed with the latest value. " - Component Props

Don't change props in Child

Generally, You should not try to change a prop inside of a child component. Because javascript objects and arrays are passed by reference, changing the prop will change the parent value. There may be rare cases where this is appropriate but most of the time it is not. Check out the following example where the prop is changed:

<div id="demo"> <intro v-bind:person="character"> </intro> <intro v-bind:person="character"> </intro> </div>
Vue.component('intro', { template: `<div> HP = {{ person.hp }} <input type='button' value='change hp' v-on:click='change()'/> </div>`, props: ['person'], methods: { change: function() { this.person.hp = 3; } } }); var app = new Vue({ el: '#demo', data: { character: { hp: 10 } } });
DO IT

Go ahead and run it, and click on the change hp. Can you see the problem?

Changing one character's hp should not change the other character's hp. When this.person.hp is called, the parent's character.hp is also changed, which causes that change to be propogated down into the other character. We want each component to be as self contained as possible.

So, how do we fix it? You initialize it with a prop and start a new variable.

Initializing with a Prop

There are times when you want to use a prop to pass down a value and then change it locally. In this case, it's better to start a new variable and initialize it with the prop.

HP = {{ myHp }}
methods: { change: function() { this.myHp = 3; } }, data: function() { return { myHp: this.person.hp } }
DO IT

Now, when you click on the change hp button, each character changes separately.

Prop Types

Let's add some types to our properties for validation. This documents your code and let's the javascript console check your code against the type of your props. Here are some simple examples:

props: { myName: String, hp: Number, isAlive: Boolean, items: Array, stats: Object }

You can specify default values too. In the second intro tag you can see that no value was provided and thus HP was set to 12.

<div id="demo"> <intro v-bind:hp="2"> </intro> <intro> </intro> </div>

Notice, we had to use v-bind:hp instead of just hp. This is to let javascript know that this is a number and not a string.

Vue.component('intro', { template: `<div> HP = {{ hp }} </div>`, props: { hp: { type: Number, default: 12 } } }); var app = new Vue({ el: '#demo' });
DO IT

Custom Validator

We can add a validator to any prop, like so:

Vue.component('intro', { template: `<div> HP = {{ hp }} </div>`, props: { hp: { type: Number, default: 12, validator: function( val ) { return val >= 0 && val <= 30; } } } }); var app = new Vue({ el: '#demo' });
DO IT

We're setting hp to 42, notice that hp is not lower than 30 therefore there will be an error.

<div id="demo"> <intro v-bind:hp="42"> </intro> <intro> </intro> </div>

Now, open the chrome debugger console and run the above and watch the console error from the validator.

Default Value for Object

Object or array defaults must be returned from a factory function.

player: { type: Object, default: function () { return { hp: 10, poisoned: false, level: 1 } } },

Multiple Possible Types

It's easy to make a field required. And you can specify multiple types in an array, like this:

player: { type: [Number, String], required: true } },

In the next lesson, we will learn about Example of how to use Vue v-model

Get the Latest Tutorial Updates
<< >>
X