Hướng dẫn thực hành Vue.js cơ bản

Khởi tạo instance Vue

Tạo một instance Vue bằng cách sử dụng new Vue(), truyền vào một đối tượng cấu hình chứa các thuộc tính như eldata.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="app">
        {{ greeting }}
    </div>
    <script>
        const appInstance = new Vue({
            el: '#app',
            data: {
                greeting: 'Xin chào!'
            }
        });
    </script>
</body>
</html>

Liên kết dữ liệu với v-bind và v-model

Sử dụng v-bind để liên kết một chiều từ dữ liệu tới phần tử giao diện, và v-model để liên kết hai chiều giữa dữ liệu và phần tử nhập liệu.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="input-demo">
        <input type="text" v-bind:value="text">
        <input type="text" v-model="text">
    </div>
    <script>
        new Vue({
            el: "#input-demo",
            data: {
                text: 'Giá trị mặc định'
            }
        });
    </script>
</body>
</html>

Sử dụng Object.defineProperty

Object.defineProperty cho phép định nghĩa getter và setter cho thuộc tính của một đối tượng, giúp theo dõi và điều khiển việc truy cập thuộc tính.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <script>
        let internalValue = 25;
        const userInfo = {
            username: 'admin',
            location: 'Hanoi'
        };

        Object.defineProperty(userInfo, 'age', {
            get() {
                console.log('Truy cập thuộc tính age');
                return internalValue;
            },
            set(newValue) {
                console.log('Thay đổi giá trị age thành:', newValue);
                internalValue = newValue;
            }
        });

        console.log(userInfo.age); 
        userInfo.age = 30; 
        console.log(internalValue); 
    </script>
</body>
</html>

Xử lý sự kiện bàn phím

Vue hỗ trợ nhiều alias cho các phím thông dụng và cho phép xử lý sự kiện bàn phím qua directive @keyup hoặc @keydown.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="keyboard-demo">
        <input @keyup.enter="handleInput" placeholder="Nhấn Enter">
        <input @keyup.space="handleInput" placeholder="Nhấn Space">
    </div>
    <script>
        new Vue({
            el: '#keyboard-demo',
            methods: {
                handleInput(event) {
                    console.log('Giá trị:', event.target.value);
                    console.log('Phím nhấn:', event.key);
                }
            }
        });
    </script>
</body>
</html>

Hiển thị tên đầy đủ bằng ba phương pháp

Có thể hiển thị tên đầy đủ bằng interpolation, phương thức trong methods, hoặc sử dụng computed properties.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="fullname-demo">
        Họ: <input v-model="firstName"><br>
        Tên: <input v-model="lastName"><br>
        Interpolation: {{ firstName }} {{ lastName }}<br>
        Methods: {{ getFullName() }}<br>
        Computed: {{ fullName }}
    </div>
    <script>
        new Vue({
            el: '#fullname-demo',
            data: {
                firstName: 'Nguyen',
                lastName: 'Van A'
            },
            methods: {
                getFullName() {
                    return this.firstName + ' ' + this.lastName;
                }
            },
            computed: {
                fullName() {
                    return this.firstName + ' ' + this.lastName;
                }
            }
        });
    </script>
</body>
</html>

Ví dụ về thời tiết

Chuyển đổi trạng thái nhiệt độ khi người dùng nhấn nút.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="weather-demo">
        <h2>Nhiệt độ hôm nay: {{ temperature }}</h2>
        <button @click="toggleTemp">Chuyển đổi</button>
    </div>
    <script>
        new Vue({
            el: '#weather-demo',
            data: {
                isHot: true
            },
            computed: {
                temperature() {
                    return this.isHot ? 'Cao' : 'Thấp';
                }
            },
            methods: {
                toggleTemp() {
                    this.isHot = !this.isHot;
                }
            }
        });
    </script>
</body>
</html>

Duyệt danh sách với v-for

Sử dụng v-for để lặp qua mảng, đối tượng, chuỗi ký tự hoặc số lần nhất định.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="list-demo">
        <ul>
            <li v-for="(person, index) in people" :key="index">
                {{ person.name }} - {{ person.age }}
            </li>
        </ul>
    </div>
    <script>
        new Vue({
            el: '#list-demo',
            data: {
                people: [
                    { name: 'An', age: 20 },
                    { name: 'Binh', age: 25 }
                ]
            }
        });
    </script>
</body>
</html>

Thêm phần tử vào danh sách

<template>
    <div>
        <button @click="addItem">Thêm mục</button>
        <p v-for="(item, idx) in items" :key="idx">{{ idx + 1 }}. {{ item }}</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            items: ['Mục 1', 'Mục 2']
        };
    },
    methods: {
        addItem() {
            this.items = [...this.items, 'Mục mới'];
        }
    }
};
</script>

Quản lý sinh viên

<template>
    <div>
        <input v-model="newStudent.name" placeholder="Tên">
        <button @click="addStudent">Thêm</button>
        <table>
            <tr v-for="(student, index) in students" :key="index">
                <td>{{ student.name }}</td>
                <td><button @click="removeStudent(index)">Xóa</button></td>
            </tr>
        </table>
    </div>
</template>

<script>
export default {
    data() {
        return {
            students: [{ name: 'Nguyen Van A' }],
            newStudent: { name: '' }
        };
    },
    methods: {
        addStudent() {
            if (!this.newStudent.name) {
                alert('Vui lòng nhập tên!');
                return;
            }
            this.students.push({ ...this.newStudent });
            this.newStudent.name = '';
        },
        removeStudent(index) {
            this.students.splice(index, 1);
        }
    }
};
</script>

Điều kiện hiển thị với v-show và v-if

v-show thay đổi thuộc tính CSS display, còn v-if thêm/xóa phần tử khỏi DOM.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="conditional-demo">
        <button @click="isVisible = !isVisible">Chuyển đổi</button>
        <img v-show="isVisible" src="image1.jpg">
        <img v-if="!isVisible" src="image2.jpg">
    </div>
    <script>
        new Vue({
            el: '#conditional-demo',
            data: {
                isVisible: true
            }
        });
    </script>
</body>
</html>

Thu thập dữ liệu biểu mẫu

Sử dụng v-model để thu thập dữ liệu từ các trường nhập liệu khác nhau.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="form-demo">
        <form @submit.prevent="handleSubmit">
            <input v-model="formData.username" placeholder="Tên đăng nhập"><br>
            <input type="radio" v-model="formData.gender" value="Nam"> Nam
            <input type="radio" v-model="formData.gender" value="Nữ"> Nữ<br>
            <input type="checkbox" v-model="formData.hobbies" value="Đọc sách"> Đọc sách
            <input type="checkbox" v-model="formData.hobbies" value="Du lịch"> Du lịch<br>
            <select v-model="formData.city">
                <option value="HN">Hà Nội</option>
                <option value="HCM">TP.HCM</option>
            </select><br>
            <button type="submit">Gửi</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#form-demo',
            data: {
                formData: {
                    username: '',
                    gender: '',
                    hobbies: [],
                    city: ''
                }
            },
            methods: {
                handleSubmit() {
                    console.log(this.formData);
                }
            }
        });
    </script>
</body>
</html>

Gán kiểu dáng động

Vue cho phép gán class và style động thông qua object hoặc array binding.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
    <style>
        .highlight { background: yellow; }
        .large { font-size: 20px; }
    </style>
</head>
<body>
    <div id="styling-demo">
        <div :class="{ highlight: isHighlighted, large: isLarge }">
            Văn bản có kiểu dáng động
        </div>
        <button @click="toggleStyle">Chuyển đổi kiểu dáng</button>
    </div>
    <script>
        new Vue({
            el: '#styling-demo',
            data: {
                isHighlighted: true,
                isLarge: false
            },
            methods: {
                toggleStyle() {
                    this.isHighlighted = !this.isHighlighted;
                    this.isLarge = !this.isLarge;
                }
            }
        });
    </script>
</body>
</html>

Bộ lọc (Filters)

Bộ lọc dùng để định dạng dữ liệu trước khi hiển thị.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="filter-demo">
        {{ price | currency }}
    </div>
    <script>
        Vue.filter('currency', function(value) {
            return new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }).format(value);
        });

        new Vue({
            el: '#filter-demo',
            data: {
                price: 1234567
            }
        });
    </script>
</body>
</html>

Directive tích hợp sẵn

  • v-text: Hiển thị văn bản thuần túy, thay thế toàn bộ nội dung.
  • v-html: Hiển thị HTML, cần thận trọng với XSS.
  • v-cloak: Ẩn phần tử cho đến khi Vue hoàn tất biên dịch.
  • v-once: Chỉ render một lần, bỏ qua cập nhật sau.
  • v-pre: Bỏ qua biên dịch cho phần tử này.
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
    <style>
        [v-cloak] { display: none; }
    </style>
</head>
<body>
    <div id="directive-demo" v-cloak>
        <span v-text="message"></span>
        <span v-html="htmlContent"></span>
        <span v-once>{{ staticText }}</span>
    </div>
    <script>
        new Vue({
            el: '#directive-demo',
            data: {
                message: 'Văn bản đơn giản',
                htmlContent: '<b>Văn bản HTML</b>',
                staticText: 'Không thay đổi'
            }
        });
    </script>
</body>
</html>

Directive tùy chỉnh

Tạo directive riêng để mở rộng chức năng.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="custom-directive-demo">
        <span v-focus>Tự động focus</span>
    </div>
    <script>
        Vue.directive('focus', {
            inserted(el) {
                el.focus();
            }
        });

        new Vue({
            el: '#custom-directive-demo'
        });
    </script>
</body>
</html>

Component không phải file đơn

Định nghĩa component bằng Vue.extend() hoặc object shorthand, sau đó đăng ký cục bộ hoặc toàn cục.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="component-demo">
        <my-component></my-component>
    </div>
    <script>
        const MyComponent = {
            template: `<div>Đây là component tùy chỉnh</div>`
        };

        new Vue({
            el: '#component-demo',
            components: {
                'my-component': MyComponent
            }
        });
    </script>
</body>
</html>

Vòng đời của component (Lifecycle Hooks)

Các hàm hook như mounted, created cho phép thực thi mã ở các giai đoạn khác nhau của vòng đời component.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
</head>
<body>
    <div id="lifecycle-demo">
        <h2 :style="{ opacity: opacityValue }">Chữ mờ dần</h2>
    </div>
    <script>
        new Vue({
            el: '#lifecycle-demo',
            data: {
                opacityValue: 1
            },
            mounted() {
                setInterval(() => {
                    this.opacityValue -= 0.02;
                    if (this.opacityValue <= 0) this.opacityValue = 1;
                }, 50);
            }
        });
    </script>
</body>
</html>

Thẻ: Vue.js JavaScript frontend web-development data-binding

Đăng vào ngày 12 tháng 9 lúc 21:38