Learning Vue

📢 This article was translated by gemini-3-flash-preview

Vue Directives

Vue uses various directives—special tag attributes prefixed with v-—to apply different functionalities to HTML tags.

v-html

Used to set an element’s innerHTML.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
    <head>
        <meta charset="utf-8">
        <title>v-html</title>
    </head>
    <body>
        <div id="app">
            <div v-html="link"></div>
        </div>
        
        <script src="js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    link:'<a href="https://yexca.net/">yexca</a>'
                }
            })
        </script>
    </body>
</html>

v-show vs. v-if

Featurev-showv-if
PurposeToggles visibilityToggles visibility (conditional rendering)
Syntaxv-show=“expression”v-if=“expression”
Valuetrue shows, false hidestrue shows, false hides
MechanismToggles style="display:none;"Directly adds or removes elements from DOM
ScenarioFrequent togglingInfrequent toggling

v-else and v-else-if

Used to assist v-if for conditional rendering. Must be placed immediately after a v-if or v-else-if element.

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-else and v-else-if</title>
    </head>
    <body>
        <div id="app">
            <p v-if="gender === 1">Gender: Male</p>
            <p v-else>Gender: Female</p>
            <hr />
            <p v-if="score >= 90">Grade: A</p>
            <p v-else-if="score >= 70">Grade: B</p>
            <p v-else-if="score >= 60">Grade: C</p>
            <p v-else>Grade: D</p>
        </div>
        
        <script src="js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    gender: 1,
                    score: 89
                }
            })
        </script>
    </body>
</html>

v-on

Used to register events: adds a listener and provides the handling logic.

Syntax 1

v-on:eventName=“inline statement”

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-on 1</title>
    </head>
    <body>
        <div id="app">
            <button v-on:click="count1--">-</button>
            <span>{{count1}} </span>
            <!-- v-on: can be replaced with @ -->
            <button @click="count1++">+</button>
            <hr />
            <button v-on:mouseenter="count2--">-</button>
            <span>{{count2}}</span>
            <button v-on:mouseenter="count2++">+</button>
        </div>
        
        <script src="js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    count1: 1,
                    count2: 2
                }
            })
        </script>
    </body>
</html>

Syntax 2

v-on:eventName=“methodName”

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-on 2</title>
    </head>
    <body>
        <div id="app">
            <button @click="fun">Toggle Visibility</button>
            <p v-show="isShow">hello yexca</p>
        </div>
        
        <script src="js/vue.js"></script>
        <script>
            const app = new Vue({
                el: "#app",
                data: {
                    isShow: true
                },
                methods: {
                    fun(){
                        // 'this' always points to the current instance
                        this.isShow = !this.isShow
                    }
                }
            })
        </script>
    </body>
</html>

Passing Arguments

Check out this example:

 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
39
40
<html>
    <head>
        <meta charset="utf-8">
        <title>v-on 3</title>
        <style>
            .box{
                border-style: solid;
                border-color: aqua;
                padding: 10px;
                margin: 10px;
                width: 200px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="box">
                <h3>Vending Machine</h3>
                <button @click="fun(5)">Coke $5</button>
                <button @click="fun(10)">Coffee $10</button>
            </div>
            <div style="padding-left: 20px;">Balance: {{balance}}</div>
        </div>
        
        <script src="../js/vue.js"></script>
        <script>
            const app = new Vue({
                el: "#app",
                data: {
                    balance: 900
                },
                methods: {
                    fun(a){
                        this.balance -= a
                    }
                }
            })
        </script>
    </body>
</html>

v-bind

Used to dynamically set HTML attributes like src, url, title, etc.

Syntax: v-bind:attributeName=“expression”

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-bind</title>
        <style>
            img{
                width: 400px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!-- v-bind can be omitted, leaving just the colon -->
            <img v-bind:src="imgURL" :title="imgTitle" :alt="imgAlt" />
        </div>
        
        <script src="../js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    imgURL: '../img/01.jpg',
                    imgTitle: 'warma',
                    imgAlt: 'warma'
                }
            })
        </script>
    </body>
</html>

v-for

Renders an element multiple times based on a data loop.

Syntax: v-for="(item, index) in array"

item: current element, index: current index.

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-for</title>
    </head>
    <body>
        <div id="app">
            <h3>fruit shop</h3>
            <ul>
                <!-- index can be omitted if not needed -->
                <li v-for="item in list">{{ item }}</li>
            </ul>
            <ul>
                <li v-for="(item,index) in list">{{ index }}</li>
            </ul>
        </div>
        
        <script src="../js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    list: ['apple', 'banana', 'watermelon']
                }
            })
        </script>
    </body>
</html>

To help Vue track and reuse list items correctly, add a unique identifier using the key attribute. The key must be a string or number and must be unique.

1
<li v-for="(item, index) in list" :key="item.id"></li>

Recommendation: Use a unique id as the key. Avoid using index as the key because it can change and won’t reliably map to the same data.

v-model

Used with form elements to achieve two-way data binding, allowing you to quickly get or set form content. Two-way binding means when the view changes, the data updates automatically, and vice versa.

Syntax: v-model=‘variable’

 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
<html>
    <head>
        <meta charset="utf-8">
        <title>v-model</title>
    </head>
    <body>
        <div id="app">
            username: <input type="text" v-model="username"/><br /><br />
            password: <input type="password" v-model="password" /><br /><br />
            <button @click="login">Login</button>
            <button @click="reset">Reset</button>
        </div>
        
        <script src="../js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
                    username: '',
                    password: ''
                },
                methods: {
                    login(){
                        console.log(this.username, this.password)
                    },
                    reset(){
                        this.username = ''
                        this.password = ''
                    }
                }
            })
        </script>
    </body>
</html>

Directive Modifiers

Suffixes indicated by a . that trigger specific behaviors.

Key Modifiers @keyup.enter: Triggers when the Enter key is released.

v-model Modifiers v-model.trim: Removes leading and trailing whitespace. v-model.number: Automatically casts input value to a number.

Event Modifiers @event.stop: Stops event propagation (bubbles). @event.prevent: Prevents the default browser behavior.

Computed Properties

Properties that are calculated based on existing data. They automatically re-evaluate when their dependencies change.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
new Vue({
    el: "#app",
    data: {
        count: 0,
    },
    computed: {
        doubleCount() {
            return this.count * 2;
        },
    },
})

Vue Lifecycle

The lifecycle refers to the entire process of an object from creation to destruction. Vue has 8 lifecycle stages. Each stage triggers a specific method (hook).

HookStage
beforeCreateBefore creation
createdAfter creation
beforeMountBefore mounting to DOM
mountedMounting complete
beforeUpdateBefore data update
updatedAfter data update
beforeDestroyBefore destruction
destroyedAfter destruction

mounted is the most commonly used hook. It indicates that Vue has initialized and the HTML has been rendered. This is where you typically fetch data from a server.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
new Vue({
    el: "#app",
    data: {
        
    },
    mounted(){
        console.log("Vue mounted. Sending request for data...");
    },
    methods: {
        
    }
})