Skip to content

Single-File Components

Giới Thiệu

Các Single-File Components của Vue (gọi là *.vue files, viết tắt là SFC) là một định dạng tệp đặc biệt cho phép chúng ta đóng gói template, logic, styling của một thành phần Vue trong một tệp duy nhất. Dưới đây là một ví dụ về SFC:

vue
<script>
export default {
  data() {
    return {
      greeting: 'Hello World!'
    }
  }
}
</script>

<template>
  <p class="greeting">{{ greeting }}</p>
</template>

<style>
.greeting {
  color: red;
  font-weight: bold;
}
</style>
vue
<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>

<template>
  <p class="greeting">{{ greeting }}</p>
</template>

<style>
.greeting {
  color: red;
  font-weight: bold;
}
</style>

Như chúng ta có thể thấy, Vue SFC là một sự mở rộng tự nhiên của ba thành phần cơ bản của HTML, CSS và JavaScript. Các khối <template>, <script>, và <style> đóng gói và đặt ở cùng một nơi cho view, logic, và styling của một thành phần trong cùng một tệp. Cú pháp đầy đủ được định nghĩa trong SFC Syntax Specification.

Tại Sao SFC

Mặc dù SFCs đòi hỏi một bước biên dịch, nhưng lại mang lại nhiều lợi ích:

SFC là một tính năng quan trọng của Vue như một framework và là phương pháp được khuyến nghị khi sử dụng Vue trong các kịch bản sau:

  • Ứng dụng Single-Page (SPA)
  • Tạo trang tĩnh (SSG)
  • Bất kỳ ứng dụng frontend phức tạp nào nơi một bước biên dịch có thể được bào chế để cải thiện trải nghiệm phát triển (DX).

Tuy nhiên, chúng tôi nhận ra có những tình huống khi SFC có thể cảm thấy quá mạnh mẽ. Điều này là lý do tại sao Vue vẫn có thể được sử dụng thông qua JavaScript thuần mà không cần một bước biên dịch. Nếu bạn chỉ muốn tăng cường HTML lớn chủ yếu với tương tác nhẹ, bạn cũng có thể kiểm tra petite-vue, một bản rút gọn của Vue tối ưu hóa cho việc nâng cao từ từ.

Cách Nó Hoạt Động

Vue SFC là một định dạng tệp đặc biệt của framework và phải được biên dịch trước bởi @vue/compiler-sfc thành JavaScript và CSS tiêu chuẩn. Một SFC đã được biên dịch là một module JavaScript (ES) tiêu chuẩn - điều này có nghĩa là với cấu hình biên dịch đúng, bạn có thể nhập một SFC như một module:

js
import MyComponent from './MyComponent.vue'

export default {
  components: {
    MyComponent
  }
}

Các thẻ <style> bên trong SFCs thường được chèn như các thẻ <style> nguyên bản trong quá trình phát triển để hỗ trợ cập nhật nhanh. Đối với production, chúng có thể được trích xuất và hợp nhất thành một tệp CSS duy nhất.

Bạn có thể chơi với SFCs và khám phá cách chúng được biên dịch trong Vue SFC Playground.

Trong các dự án thực tế, chúng tôi thường tích hợp trình biên dịch SFC với các công cụ biên dịch như Vite hoặc Vue CLI (dựa trên webpack), và Vue cung cấp các công cụ tổ chức chính thức để giúp bạn bắt đầu với SFCs một cách nhanh chóng. Xem thêm chi tiết trong phần SFC Tooling.

Làm Sao Với Việc Tách Biệt Các Mối Quan Tâm?

Một số người dùng đến từ một lĩnh vực phát triển web truyền thống có thể quan ngại rằng SFCs đang kết hợp các mối quan tâm khác nhau ở cùng một nơi - mà theo lý thuyết, HTML/CSS/JS nên được tách biệt!

Để trả lời câu hỏi này, quan trọng là chúng ta đồng thuận rằng sự tách biệt giữa các mối quan tâm không phải là việc tách biệt giữa các loại tệp. Mục tiêu cuối cùng của nguyên tắc kỹ thuật là cải thiện khả năng bảo trì của mã nguồn. Sự tách biệt giữa các mối quan tâm, khi được áp dụng cứng nhắc như sự tách biệt giữa các loại tệp, không giúp chúng ta đạt được mục tiêu đó trong bối cảnh ứng dụng frontend ngày càng phức tạp.

Trong phát triển UI hiện đại, chúng ta thấy rằng thay vì chia codebase thành ba lớp lớn tương tác với nhau, việc chia thành các thành phần lỏng lẻo và kết hợp chúng làm nhiều ý nghĩa hơn. Bên trong một thành phần, template, logic và styles của nó tự nhiên liên kết với nhau, và việc đặt chúng ở cùng một nơi thực sự làm cho thành phần trở nên gắn kết và dễ bảo trì hơn.

Lưu ý rằng ngay cả khi bạn không thích ý tưởng của Single-File Components, bạn vẫn có thể tận dụng các tính năng tự động nạp lại và biên dịch trước của chúng bằng cách tách JavaScript và CSS của bạn thành các tệp riêng biệt sử dụng Src Imports.

Single-File Components has loaded