Learn the basics of VueJS (Part 2)
- Tram Ho
Preamble:
In the previous part, I showed you how to install Vuejs and the lifecycle of an object in Vuejs. Now let’s go to learn more about Computed property and watcher, Binding by class and style, Render by condition and by list.
Computed property and watcher:
1. Computed property:
Computed property can be understood as a “computed property”. It is represented as a method or an object containing the setter and getter methods. Usually when we calculate simple processing operations in the template, we will write the function directly in the template by placing the function inside the {{ }} syntax. But this with complex processing operations put into the template, it will look very confusing and more difficult to maintain, then we need to use the Computed property.
How to declare use Computed property:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <template> <div id="my-id"> Hello world </div> </template> <script> export default { data () { return { msg: 'Hello world' } }, computed: { } } </script> |
Here’s a simple example of how to handle it directly on the template and handle it via Computed property :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <template> <div id="my-id"> <p>Message ban đầu: "{{ msg }}"</p> <p>Message in hoa trong template: "{{ msg.toUpperCase() }}"</p> <p>Message in hoa trong computed: "{{ convertMessageByComputed }}"</p> <p>Message in hoa trong method: "{{ convertMessageByMethod() }}"</p> </div> </template> <script> export default { data () { return { msg: 'Demo Vuejs' } }, computed: { convertMessageByComputed: function () { return this.msg.toUpperCase() } }, methods: { convertMessageByMethod: function () { return this.msg.toUpperCase() } } } </script> |
And this is the result:
According to my example, you must be wondering why we don’t use it methods but have to use computed? Because functions do not need to pass such parameters when using computed performance will be maximized due to the cache mechanism that when rendered without change, it will always take the value in cache.
2. Watcher:
Watcher in Vuejs Used to track and monitor data changes and take action accordingly. To declare watcher in Vuejs , you need to adhere to the following 2 principles:
- The name of the watcher must match the name of the data to be monitored.
- The watcher must be placed in the watch scope.
Syntax example:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <script> export default { data: { name: 'Nguyen Van Huy' }, watch: { name : function () { console.log(this.name); } } } </script> |
3. Perform computed comparisons, watch and methods:
Computed | watch | methods | |
---|---|---|---|
Done when? | Dependent properties change | Attribute change monitoring | re-render the page |
Parameters | No | Yes | Yes |
Use when? | When manipulating data without wanting to recalculate | When the data is large and constantly changing | When you need a regular function or a function with parameter rights |
Binding for classes and styles:
During the development of your project there may come a time when you want to add a class or a style attribute to an HTML tag with a certain condition occurring. Since both class and style are attributes, we can use v-bind to handle them. Vue provides some support when v-bind is used with classes and styles. Not only strings, these expressions can handle both arrays and objects.
1. Binding class in HTML:
- Using object: We can consider the following example of what bind 1 class and many classes would look like:1234567891011121314151617//bind 1 class<div v-bind:class="{ active: isActive }">Hello world</div>//bind nhiều class<div v-bind:class="{ active: isActive, bold: isBold }">Hello world</div>//Bật tắt active<div><button @click="isActive = !isActive">Active text</button></div>//Bật tắt bold<div><button @click="isBold = !isBold">Active text</button></div>
Pass the data in as follows:1234567891011<script>export default {data() {return {isActive: true,isBold: false}}}</script>
Now let’s style the classes we just created:123456789<style lang="scss" scoped>.active {display: none;}.bold {font-weight: bold;}</style>
So, here we declare the default value for the variableisActive
andisBold
. When clicking on the button declared buttons above, the values for the corresponding variables will be changed.And Vue also allows you to pass 1 Object to the bind class as follows:
123//Bind 1 classObject<div v-bind:class="classObjectBind">Hello world</div>Data transmission:
12345678910111213<script>export default {data() {return {classObject: {active: true,bold: false}}}}</script> - Using arrays: Similar to using Object, using arrays will be declared as follows:
<div v-bind:class="[activeClass, boldClass]"></div>
Data transmission:1234567891011<script>export default {data() {return {activeClass: 'active',boldClass: 'bold'}}}</script>
2. Binding for inline style:
Binding for inline style in usage is quite similar to Binding class in HTML, very simple syntax – looks like CSS normally, only it is a object JavaScript.
The basic example is as follows:
<div v-bind:style="{ color: Color, fontSize: fontSize + 'px' }">Hello world</div>
Data transmission:
1 2 3 4 5 6 7 8 9 10 11 | <script> export default { data() { return { Color: 'green', fontSize: 18 } } } </script> |
Usually we should bind to a style-specific Object to make your code look cleaner. Examples are as follows:
<div v-bind:style="styleObject"></div>
Data transmission:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <script> export default { data() { return { styleObject: { color: 'green', fontSize: '18px' } } } } </script> |
If you use the css multiple-valued attribute, Vue has also supported you by:
<div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
In this case, Vue will automatically select the appropriate attribute for the browser you are using.
Conditional Render:
In a large or small project, you’ve certainly had to do with conditional statements. Similarly, Vue provides us with directives to consider conditions and usage quite similar to other programming languages that you have ever learned. Let’s go through it together.
1. v-if:
v-if
is 1 directive must be used on a single element eg <div>
….. help us manage rendering.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <template> <div> <div class="class1" v-if="isActive == True"> Hello world </div> <div> <button @click="isActive = !isActive">Button</button> </div> </div> </template> <script> export default { data() { return { isActive: true } } } </script> |
According to the example above, we can check the display condition of an element that you want and you can also see that the usage is not different from other languages you learn.
2. v-else:
Similar to v-if
, directivev-else
This acts as a block “else” by v-if
and v-else
must be right behind directivev-if
or v-else-if
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <template> <div> <div class="class1" v-if="isActive == True"> Hello world 1 </div> <div class="class2" v-else> Hello world 2 </div> <div> <button @click="isActive = !isActive">Button</button> </div> </div> </template> <script> export default { data() { return { isActive: true } } } </script> |
3. v-else-if:
Similar to v-else
, directive v-else-if
acts as a block “else-if” by v-if
and they can be used repeatedly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <template> <div> <div class="class1" v-if="count == 1"> Hello world 1 </div> <div class="class2" v-else-if="count == 2"> This is block 2 </div> <div class="class3" v-else> Hello world 3 </div> <div> <button @click="setcount(1)">Show hello world 1</button> </div> <div> <button @click="setcount(2)">Show hello world 3</button> </div> <div> <button @click="setcount(3)">Show hello world 3</button> </div> </div> </template> <script> export default { data() { return { count: 1 } }, methods: { setcount(count_change) { this.count = count_change } } } </script> |
4. v-show:
Directive v-show
is also an option for render according to the same condition and usage as v-if
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <template> <div> <div class="class1" v-show="isActive == True"> Hello world </div> <div> <button @click="isActive = !isActive">Button</button> </div> </div> </template> <script> export default { data() { return { isActive: true } } } </script> |
Let’s take a look and see if it returns something similar to v-if
when click button.
So why have these 2 directives when the results are similar?
Because directive v-show
will always be rendering in the DOM and only be visible using the CSS properties. Still v-if
then it depends on the test condition to render DOM.
Render by list (v-for):
Directive v-for
we use to render a list based on an array, in projects we will use it often.
Let’s go into an example so you can understand better.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <template> <div class="test-list"> <ul> <li v-for="student in students">{{ student.full_name }}</li> </ul> </div> </template> <script> export default { data() { return { students: [ { full_name: 'Nguyen Van A' }, { full_name: 'Nguyen Thi B' }, { full_name: 'Nguyen Van C' }, { full_name: 'Nguyen Thi D' } ] } } } </script> |
We can v-for
1 object as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <template> <div class="test-list"> <ul> <li v-for="(value, key) of student">{{ key }} - {{ value }}</li> </ul> </div> </template> <script> export default { data () { return { student: { name: 'Nguyen Van A', age: '20', address: 'Ha Noi', email: 'email@gmail.com' } } } } </script> |
Please notice that v-for
the sort order of the parameters will be (value, key, index)
with index
is the sequence number of the attribute. We can v-for
with a sequence of numbers:
1 2 3 4 | <div> <span v-for="i in 100">{{ i }} </span> </div> |
And you can also v-for directly with the component as a normal element:
<my-component v-for="item in items" :key="item.id"></my-component>
In order for Vue to be able to recognize each node and thereby reuse and arrange elements, you need to provide an attribute key
with a unique value for each item.
1 2 3 4 5 | <!-- ở đây ta dùng shorthand `:key` thay vì `v-bind:key` --> <div v-for="item in items" :key="item.id"> <!-- nội dung --> </div> |
Vue recommended to use the key whenever you use v-for
, unless the DOM content being traversed is too simple or you are intentionally using the default behavior of Vue to speed up the application.
v-for and v-if:
When v-for and v-if are used on the same node, v-for will have higher precedence than v-if and v-if executes on each loop of v-for, reducing the speed. handle. These two directives should only be used when you want to render some items according to your desired conditions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <template> <div class="test-list"> <ul> <li v-for="student in students" v-if="student.age < 20">{{ student.full_name }} - tuổi : {{ student.age }} </li> </ul> </div> </template> <script> export default { data () { return { students: [ { full_name: 'Nguyen Van A', age: '18' }, { full_name: 'Nguyen Thi B', age: '19' }, { full_name: 'Nguyen Van C', age: '20' }, { full_name: 'Nguyen Thi D', age: '21' }, ] } } } </script> |
The above example will only render students under 20 years old.
Please note that From version 2.2.0 onwards, the key attribute is required when using v-for with a component.
Summary:
So in this article, I introduced you to Computed property and watcher, Binding by class and style, Render by condition and by list in Vuejs to help you understand the basics of Vue. I look forward to receiving your comments. Thank you for listening to my sharing. Good luck!