Vue.js is a versatile & popular framework for building web user interfaces. Even I feel, compare to other UI frameworks, Vue framework seems to be easier to learn & code. There are four basic & major concepts of Vue framework which often seems to be confusing from each others, specially for beginners.
These four concepts on which entire vue page/components depends on are:
1. data()
2. props
3. computed and
4. methods
Here I’ll try to explain these concepts and also make sure there won’t be any more confusion around them to use it. For the article below, I’ll be using below example for explanation so please pay attention to it but don’t worry as I'll explain what I did here.
App.vue
<script>
export default {
data() {
return {
firstName: 'Binod',
lastName: 'Mahto',
fullName:'',
methodcount:0,
computedcount:0
}
},
methods : {
mtdCalculateFullName() {
this.$data.methodcount++;
this.$data.fullName = this.$data.firstName + ' ' + this.$data.lastName;
}
},
computed : {
cmptCalculateFullName() {
this.$data.computedcount++;
this.$data.fullName = this.$data.firstName + ' ' + this.$data.lastName;
}
}
}
</script><template>
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
<div>
<button @click='mtdCalculateFullName()'>
Click Me
</button>
<p>Full Name:</p><p>{{fullName}}</p>
<p>count: {{methodcount}}</p>
</div>
<div>
<button @click='cmptCalculateFullName'>
Click Me
</button>
<p>Full Name:</p><p>{{fullName}}</p>
<p>count: {{computedcount}}</p>
</div>
</template>
Let’s discuss the concepts now.
data():
by definition, it is a function that returns the initial reactive state for the component instance.
Technically it is a data placeholder which keeps the state of data throughout the component/page life cycle. For backend programmer, it is like class variables which holds the data state for the class.
In above example here, I have five data members to capture the data state for my vue page and they are defined as:
data() {
return {
firstName: 'Binod',
lastName: 'Mahto',
fullName:'',
methodcount:0,
computedcount:0
}
}
The syntax is like a function named ‘data()’ which returns a type holding members and it is consumed within the script as
this.$data.{datamembername}
//not necessary to use $data instead you do this.{datamembername} but i'm doing this for readability purpose.
This member’s value can be modified through out the page/component lifecycle and it will retain the state for the same. In my example, I’m using the same data member in UI component to bind with <input/> as well to display it in html.
Hence, as the name says data(), the purpose of it is to maintain the data for throughout the component life cycle.
props:
props are one-way-down data binding technique to bind between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. Hence for the child component it is read only.
For an example let’s create a reusable component which has a template to display messages passed by parent and this is what exactly the props serves.
Here is the component : MyComp.vue
<template>
<div>
<p>{{greetingMessage}}</p>
</div>
</template><script>
export default {
props: ['greetingMessage']
}
</script>
and use this component in parent component as:
<script>
import MyComp from './MyComp.vue' //import it firstexport default {
components: {
MyComp //define the component
},
data() {
return {
message: 'Hi This is a message for props',
}
},
}
</script><template>
<MyComp greetingMessage ='Hi This is props'></MyComp>
<MyComp greeting-Message ='Hi This is props'></MyComp>
<MyComp :greeting-Message ='message'></MyComp>
</div>
</template>
Above code will display the message passed by parent in the child component. Hope you noticed something here, I have used the child component in three different ways and the purpose was to make you aware so that you will not get confused.
In short, from the above code greeting-Message (pascal case) is the standard suggested to follow to keep code inline with html syntax and when you need to bind the data member, you will have to use the props with ‘:’ as prefix i.e. :greeting-Message =’message’.
one more thing, if you noticed the props (you can call it property) I defined in child component, looks like an array and this is one way of defining it. Vue framework allows you to define in other way also (like an object). i.e.
<template>
<div>
<p>{{greetingMessage}}</p>
</div>
</template>
<script>
export default {
props: {
greetingMessage : string,
}
}
</script>
It’s all your call, vue framework allows both. In any way, in case of complex object for props you would need the second way of declaration.
Hence, props are a way of one-way data binding technique to pass value from parent to child and not vice versa.
methods:
methods allows you to create your re-usable functions to perform your logic. it takes parameters and returns output or void. Syntax for defining methods is:
methods:{
mymethod1(payload: any){
//logic goes here
}
//syntax to define async methods
async mymethod2(payload: any){
//logic goes here
}
}
In my first example, I have a method called ‘mtdCalculateFullName’ which formats the full name string and save it back to data() function member.
Hence, methods provides to define functions which perform certain action, logic etc. These functions you can call within a function or you can bind to action event also. i.e.
<button @click='mtdCalculateFullName()'>
computed:
This is similar to methods in terms of syntax or use but it is not really similar and it has a great purpose behind it. This is where most of the people get confused between methods and computed.
computed allows you to define properties or methods with the reactive dependencies of the data and the output of computed property or function is cached (and will not be re-executed or calculated) until data state changes.
Not clear, no worries, plz pay attention to my first example here (App.vue) which has a computed member (function) named ‘cmptCalculateFullName()’ which formats the full name as the methods member (function) named ‘mtdCalculateFullName()’ does. Both the functions increment the data variable named computedcount and methodcount respectively when the specific function is being called on click on respective buttons.
When you run the example, you will see the output as:
and here is the key fact: no matter how many times you are clicking the second button, count value will not change for second div unless you change the firstName and lastName from the input text box and that is the purpose of computed property or function, where as you will always see the count value increasing on click of 1st button because the methods function is being re-executed every time it is being called but computed function’s data is cached and ignore the execution unless data is changed.
Hence, computed allows you to create property or function which works with reactive dependencies of data member by caching the output until data changes.
I hope this made you clear the purpose of method and computed concepts of the vue framework. Now let me give you one simple example with respect to computed: Suppose in your application component you have data() member which is array of string data, example countries :[‘India’, ‘Japan’, …]. In your component you bind this data multiple places but by sorting it in a ascending order. So in this case, the best option to use computed member instead of method to gain the performance.
One more confusing fact, In some articles you may find people saying that, “computed doesn’t allow parameter but methods does allow” is as one of the difference but this statement is partially true, let’s see how.
This is true that computed function doesn’t allow function’s input parameter but the same can be achieved through getters, setters property of computed member, here is the example:
export default {
data() {
return {
firstName: 'Binod',
lastName: 'Mahto'
}
},
computed: {
computedFullName: {
// getter
get() {
return this.$data.firstName + ' ' + this.$data.lastName
},
// setter
set(newValue) {
// Note: we are using destructuring assignment syntax here.
[this.$data.firstName, this.$data.lastName] = newValue.split(' ')
}
}
}
}
You can call this getters, setters as:
this.computedFullName = 'James Bond';//to set the new value
this.computedFullName; // to get the value.
Hence, though computed doesn’t allow you to do this:
//this is not allowed
computed:{
cmptCalculateFullName(payload : string)
{
}
}
but then you have the way to achieve the same using setters:
computed: {
computedFullName: {
// setter
set(newValue) {
// Note: we are using destructuring assignment syntax here.
[this.$data.firstName, this.$data.lastName] = newValue.split(' ')
}
}
}
Hence saying that, computed doesn’t allow payload input parameter is partially true because though it is not possible through computed function but by computed member’s setter you can achieve the same.
That’s all. Hope you enjoyed the content, don’t forget to follow me for more like this and like/comment for it please. Happy programming.
Reference:
Also, you don’t need any tool or to install anything, to try above example instead you can do this via vue’s SFC playgorund: https://sfc.vuejs.org/
No comments:
Post a Comment