GIỚI THIỆU
CĂN BẢN
NÂNG CAO
VUEJS 2X CĂN BẢN
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

10 best practices trong VueJS 2

Trong bài viết này, mình sẽ tìm hiểu 10 Best Practices quan trọng nhất khi làm việc với VueJS 2. Từ việc quản lý components đến cách xử lý props, từ việc sử dụng directive đến cách tối ưu hóa hiệu suất, mình sẽ đi sâu vào từng quy tắc và lý do tại sao chúng là quan trọng đối với quá trình phát triển ứng dụng VueJS 2.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Những best practices này không chỉ giúp tăng cường sự dễ bảo trì của ứng dụng mà còn tạo nên một cơ sở codebase chất lượng, dễ đọc và dễ mở rộng. Hãy cùng bắt đầu tìm hiểu những nguyên tắc và thực hành mà khi áp dụng, chúng sẽ giúp tối ưu hóa quá trình phát triển VueJS 2 của bạn.

Vue Best Practices and Security 1 1280x720 jpg

1. Sử dụng :key với v-for trong VueJS 2

Giải thích về :key và vấn đề khi không sử dụng nó

Khi sử dụng directive v-for trong VueJS để render danh sách các phần tử, việc sử dụng :key là một phần quan trọng không thể bỏ qua. :key được sử dụng để định danh duy nhất cho mỗi phần tử trong danh sách, giúp Vue xác định các phần tử cần cập nhật khi dữ liệu thay đổi.

Bài viết này được đăng tại [free tuts .net]

Khi không sử dụng :key, Vue sẽ cố gắng tái sử dụng và cập nhật lại các phần tử dựa trên thứ tự và nội dung của chúng, thay vì dựa vào định danh duy nhất. Điều này có thể dẫn đến các vấn đề về hiệu suất và tính nhất quán khi dữ liệu thay đổi.

Để minh họa, dưới đây là một ví dụ cụ thể về việc sử dụng :key:

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
        { id: 3, name: 'Item 3' }
      ]
    };
  },
  // Giả sử khi dữ liệu thay đổi
  methods: {
    updateItems() {
      this.items = [
        { id: 2, name: 'Item 2 - Updated' },
        { id: 3, name: 'Item 3' },
        { id: 4, name: 'Item 4 - New' }
      ];
    }
  }
};
</script>

Trong ví dụ này, :key="item.id" giúp Vue xác định mỗi phần tử dựa trên id duy nhất của nó, giúp quản lý và cập nhật danh sách các phần tử một cách chính xác khi dữ liệu thay đổi.

2. Sử dụng Kebab-case cho Events trong VueJS 2

Khái niệm và cách thực hiện kebab-case với events

Trong VueJS, khi gửi và lắng nghe sự kiện, việc sử dụng kebab-case (viết thường và phân cách bằng dấu gạch ngang '-') cho tên sự kiện giúp thống nhất và dễ quản lý hơn.

Kebab-case là một quy ước đặt tên bằng cách sử dụng chữ thường và dấu gạch ngang để phân tách các từ, ví dụ: choose-this-item, item-selected,...

Khi gửi sự kiện trong một component con:

// Trong component con
this.$emit('choose-this-item');

Việc sử dụng kebab-case giúp rõ ràng hóa tên sự kiện và dễ dàng hiểu rõ ý nghĩa của nó.

Khi lắng nghe sự kiện từ component cha:

<!-- Trong component cha -->
<child-component @choose-this-item="handleChooseItem" />

Lưu ý rằng, sự kiện được lắng nghe cũng phải được viết theo kebab-case để đảm bảo tính thống nhất và dễ quản lý.

Thống nhất cách đặt tên events để dễ quản lý và tái sử dụng

  • Đồng nhất hóa conventions: Đảm bảo rằng mọi người trong dự án đều sử dụng cùng một quy ước đặt tên sự kiện. Điều này giúp làm rõ ý nghĩa của sự kiện và tạo điều kiện cho việc tái sử dụng component một cách dễ dàng.

  • Mô tả rõ ràng: Tên sự kiện nên phản ánh hành động hoặc sự kiện cụ thể đang xảy ra. Ví dụ, item-selected, button-clicked,...

  • Tuân thủ nguyên tắc: Luôn sử dụng kebab-case khi đặt tên sự kiện để duy trì tính nhất quán và dễ đọc.

  • Tài liệu hóa: Ghi chú rõ ràng về ý nghĩa của từng sự kiện trong tài liệu hoặc comment trong code để giúp người khác hiểu và tái sử dụng dễ dàng hơn.

Việc sử dụng kebab-case cho tên sự kiện không chỉ làm cho codebase rõ ràng hơn mà còn tạo điều kiện thuận lợi cho việc bảo trì và tái sử dụng component trong dự án.

3. Khai báo Props với CamelCase và Kebab-case trong VueJS 2

Thông tin về conventions của các ngôn ngữ và VueJS

Trong lập trình, conventions đối với việc đặt tên có thể khác nhau giữa các ngôn ngữ và framework. Trong Javascript, convention thường sử dụng CamelCase (viết hoa ký tự đầu của từ thứ 2 và các từ tiếp theo liền nhau, không có khoảng trắng), trong khi HTML và CSS thường sử dụng Kebab-case (viết thường và phân tách bằng dấu gạch ngang) cho các thuộc tính.

Trong VueJS, khi sử dụng props, nó tự động chuyển đổi từ CamelCase sang Kebab-case khi sử dụng trong phần template, nhưng vẫn giữ nguyên CamelCase khi sử dụng trong script. Điều này có nghĩa là bạn có thể sử dụng conventions mà bạn quen thuộc trong script, và Vue sẽ tự động chuyển đổi chúng cho phù hợp với conventions của HTML.

Cách khai báo props cho script và template để thống nhất conventions

Khai báo trong script: Sử dụng CamelCase khi khai báo props trong phần script của component.

<script>
export default {
  props: {
    productName: String,
    productPrice: Number,
    // ...
  }
}
</script>

Sử dụng trong phần template: Vue sẽ tự động chuyển đổi CamelCase thành Kebab-case khi sử dụng props trong phần template. Vì vậy, bạn có thể sử dụng Kebab-case cho props trong phần template một cách tự nhiên.

<template>
  <div>
    <p>{{ productName }}</p>
    <p>{{ productPrice }}</p>
    <!-- ... -->
  </div>
</template>

Lưu ý rằng, việc này giúp giữ tính nhất quán giữa conventions của các ngôn ngữ và framework, làm cho code dễ đọc và bảo trì hơn. Bạn không cần phải lo lắng về việc chuyển đổi conventions, VueJS sẽ tự động xử lý phần này giúp cho việc làm việc với props trở nên dễ dàng và hiệu quả hơn.

4. Luôn sử dụng Function Return cho Data trong VueJS 2

Hiểu về vấn đề reference data giữa các component

Trong VueJS, khi khai báo dữ liệu trực tiếp trong một component thông qua object, các component sẽ chia sẻ tham chiếu tới cùng một object nếu được sử dụng nhiều lần. Điều này có thể dẫn đến vấn đề khi một component thay đổi dữ liệu và làm thay đổi dữ liệu của các component khác một cách không mong muốn. Vấn đề này xuất phát từ việc các component sử dụng cùng một tham chiếu dữ liệu.

Lợi ích và cách thực hiện function return cho data

  • Tránh reference data chia sẻ: Sử dụng function return cho data sẽ tạo ra một instance mới của dữ liệu cho mỗi component. Điều này giúp tránh việc chia sẻ reference dữ liệu giữa các component.

  • Bảo toàn tính riêng tư của dữ liệu: Mỗi component sẽ có bản sao riêng biệt của dữ liệu, không ảnh hưởng đến dữ liệu của các component khác.

Để thực hiện function return cho data, bạn có thể sử dụng một hàm để trả về dữ liệu thay vì trực tiếp trả về một object. Ví dụ:

<script>
export default {
  data() {
    return this.getDefaultData();
  },
  methods: {
    getDefaultData() {
      return {
        product: 'Product 1',
        quantity: 10,
        // ... other properties
      };
    },
  },
};
</script>

Khi sử dụng getDefaultData() để khởi tạo data, mỗi lần component được tạo ra, nó sẽ nhận được một bản sao mới của dữ liệu được trả về từ hàm này, đảm bảo rằng mỗi component sẽ có dữ liệu riêng và không chia sẻ tham chiếu. Điều này giúp duy trì tính riêng tư và ngăn chặn tình trạng không mong muốn khi một component thay đổi dữ liệu và ảnh hưởng đến các component khác.

5. Không Sử Dụng v-if với v-for trong VueJS 2

Vấn đề khi sử dụng cả v-if và v-for cùng lúc

Khi sử dụng cả v-if (điều kiện hiển thị) và v-for (lặp qua danh sách) cùng một lúc trên cùng một phần tử trong VueJS, điều này có thể gây ra vấn đề về hiệu suất và logic không mong muốn.

Khi bạn sử dụng v-if trong mỗi phần tử được tạo bởi v-for, Vue sẽ kiểm tra điều kiện v-if trên từng phần tử trong danh sách. Điều này có thể dẫn đến việc render ra các phần tử không cần thiết, tốn tài nguyên và giảm hiệu suất của ứng dụng.

Cách thay thế bằng computed property để lọc dữ liệu

Thay vì sử dụng v-if và v-for cùng lúc, một cách hiệu quả là sử dụng computed property để lọc dữ liệu trước khi hiển thị trong template. Điều này giúp tạo ra một danh sách mới chứa các phần tử được lọc dựa trên điều kiện mà không ảnh hưởng đến hiệu suất.

Ví dụ, thay vì:

<template>
  <div>
    <div v-for="item in items" v-if="item.price < 500">
      {{ item.name }}
    </div>
  </div>
</template>

Bạn có thể sử dụng một computed property để lọc dữ liệu trước khi hiển thị:

<template>
  <div>
    <div v-for="cheapItem in cheapItems" :key="cheapItem.id">
      {{ cheapItem.name }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: 'Item 1', price: 400 },
        { id: 2, name: 'Item 2', price: 600 },
        { id: 3, name: 'Item 3', price: 300 },
        // ...
      ]
    };
  },
  computed: {
    cheapItems() {
      return this.items.filter(item => item.price < 500);
    }
  }
};
</script>

Khi sử dụng computed property cheapItems, bạn chỉ render ra những phần tử đã được lọc với điều kiện price < 500, giúp cải thiện hiệu suất và duy trì logic rõ ràng trong template.

6. Validate Dữ Liệu Của Props trong VueJS 2

Ý nghĩa và lợi ích của việc validate props

Khi xây dựng một ứng dụng VueJS, việc validate dữ liệu của props giúp đảm bảo rằng component sẽ nhận được dữ liệu đúng đắn từ phía parent component. Validate props giúp kiểm tra và đảm bảo rằng dữ liệu được truyền vào props đáp ứng các yêu cầu cụ thể, từ loại dữ liệu đến các giá trị cần thiết.

Lợi ích của việc validate props bao gồm:

  • Bảo đảm tính nhất quán của dữ liệu: Validate props giúp xác nhận rằng dữ liệu được truyền từ parent component là hợp lệ, giúp tránh lỗi logic hoặc hiển thị không đúng.
  • Tăng cường độ tin cậy của component: Component sẽ hoạt động đúng đắn hơn khi dữ liệu mà nó nhận được được kiểm tra trước.
  • Tài liệu hóa rõ ràng hơn: Validate props cũng giúp làm rõ về yêu cầu và loại dữ liệu được chấp nhận, tạo điều kiện cho việc sử dụng và bảo trì component dễ dàng hơn.

Sử dụng validator và required để làm rõ các giá trị hợp lệ

Trong VueJS, bạn có thể sử dụng các thuộc tính như type, validator, và required để validate props. Ví dụ:

<script>
export default {
  props: {
    status: {
      type: String,
      required: true,
      validator: function(value) {
        return ['syncing', 'synced', 'version-conflict', 'error'].indexOf(value) !== -1;
      }
    }
  }
};
</script>

Trong ví dụ trên:

  • type xác định kiểu dữ liệu cần thiết cho props (trong trường hợp này là String).
  • required: true đảm bảo rằng props này là bắt buộc phải được truyền vào component.
  • validator là một hàm custom để kiểm tra giá trị của props. Nếu giá trị không thoả mãn điều kiện trong hàm validator, validate sẽ fail và console sẽ hiển thị một cảnh báo.

Việc này giúp bảo vệ component khỏi dữ liệu không hợp lệ và cung cấp thông tin rõ ràng về các yêu cầu của props cho những người sử dụng component.

7. Thống Nhất Tên File Component trong VueJS 2

Quan Trọng của việc đặt tên File trong môi trường làm việc nhóm

Việc thống nhất cách đặt tên file trong môi trường làm việc nhóm đóng vai trò quan trọng trong việc tổ chức và duy trì dự án. Các quy ước đặt tên file cung cấp cách tiếp cận chung và giao diện chuẩn giữa các thành viên trong nhóm. Điều này có nhiều lợi ích:

  • Dễ dàng tìm kiếm và duy trì: Khi mọi người sử dụng cùng một quy ước đặt tên, việc tìm kiếm và duy trì file trở nên dễ dàng hơn, giúp tiết kiệm thời gian và công sức.

  • Hiểu quả hơn trong việc đọc mã nguồn: Các tên file thống nhất giúp người đọc hiểu được nội dung của file một cách nhanh chóng, giảm thời gian cần thiết để tìm hiểu cấu trúc của dự án.

  • Tạo điều kiện cho việc mở rộng dự án: Khi các file được đặt tên một cách nhất quán, việc mở rộng dự án và thêm các thành phần mới trở nên dễ dàng hơn và ít xung đột hơn.

Lựa chọn giữa PascalCase và kebab-case và duy trì cách đặt tên này

  • PascalCase: Đây là quy ước đặt tên với việc viết hoa chữ cái đầu của mỗi từ, không có dấu cách hoặc ký tự đặc biệt. Ví dụ: MyComponent.vue, BaseButton.vue.

  • Kebab-case: Quy ước đặt tên viết thường và phân cách bằng dấu gạch ngang. Ví dụ: my-component.vue, base-button.vue.

Việc lựa chọn giữa PascalCase và kebab-case phụ thuộc vào sở thích và quy ước được thiết lập trong dự án hoặc nhóm làm việc. Tuy nhiên, quan trọng nhất là duy trì tính nhất quán trong cách đặt tên file và tuân thủ quy ước được chọn.

Để duy trì tính nhất quán, quyết định và thống nhất một cách rõ ràng với nhóm là quan trọng. Sau đó, duy trì việc áp dụng quy ước đặt tên đã được chọn và hướng dẫn cho các thành viên mới trong nhóm để đảm bảo tính nhất quán trong toàn bộ dự án.

8. Sử Dụng Prefix Cho Các Base Component trong VueJS 2

Ý Nghĩa của việc nhóm các Base Component

Các base component là những thành phần cơ bản, có thể tái sử dụng và thường xuyên được dùng trong dự án. Việc nhóm chúng lại giúp tạo ra một tập hợp các thành phần cơ bản, độc lập và dễ dàng tái sử dụng trong toàn bộ project. Điều này mang lại nhiều lợi ích:

  • Dễ dàng quản lý: Nhóm các base component giúp dễ dàng tìm kiếm, duy trì và cập nhật chúng khi cần thiết.

  • Tăng khả năng tái sử dụng: Base component thường chứa các phần tử giao diện cơ bản, có thể tái sử dụng ở nhiều nơi trong dự án, giúp tiết kiệm thời gian và công sức.

Cách đặt Prefix và quản lý các Base Component trong Project

  • Đặt Prefix cho Base Component: Việc đặt prefix cho các base component giúp phân biệt chúng với các component khác và làm cho việc tìm kiếm và quản lý dễ dàng hơn. Ví dụ, BaseButton.vue, BaseInput.vue, BaseCard.vue.

  • Quản Lý Base Component: Các base component thường được tổ chức trong một thư mục riêng biệt hoặc một cấu trúc thư mục cụ thể. Bạn có thể tạo một thư mục có tên như base-components hoặc common-components để chứa các thành phần này.

  • Import Global trong Project: Để sử dụng các base component một cách dễ dàng, bạn có thể import chúng global trong dự án. Điều này có thể được thực hiện trong file cấu hình chính của ứng dụng (ví dụ: main.js hoặc App.vue):

import BaseButton from '@/components/base-components/BaseButton.vue';
import BaseInput from '@/components/base-components/BaseInput.vue';
// ...

Vue.component('BaseButton', BaseButton);
Vue.component('BaseInput', BaseInput);
// ...

Tạo Documentation hoặc Guidelines: Để hướng dẫn cho các thành viên trong nhóm về cách sử dụng và quản lý base component, bạn có thể tạo tài liệu hoặc hướng dẫn rõ ràng để đảm bảo tính nhất quán trong dự án.

Việc sử dụng prefix và quản lý các base component một cách cẩn thận giúp tối ưu hóa quá trình phát triển, tạo điều kiện cho việc tái sử dụng và bảo trì dễ dàng hơn trong dự án.

9. Sử dụng một cách thống nhất các Directive trong VueJS 2

Trong VueJS, có các shorthand directive giúp viết code ngắn gọn hơn và dễ hiểu hơn:

  • @: Shorthand cho v-on, sử dụng để lắng nghe các sự kiện.

  • :: Shorthand cho v-bind, sử dụng để gán giá trị vào các thuộc tính hoặc prop.

  • #: Shorthand cho v-slot, sử dụng để làm việc với slots trong Vue.

Lợi ích:

  • Ngắn gọn và dễ đọc: Sử dụng shorthand directive giúp code ngắn gọn hơn, dễ đọc và dễ hiểu hơn so với việc sử dụng cú pháp đầy đủ.
  • Tính nhất quán: Việc sử dụng shorthand directive theo cách thống nhất giữa các thành viên trong nhóm làm việc giúp bảo đảm tính nhất quán trong codebase.

Cách sử dụng một cách rõ ràng và dễ hiểu:

  • @ (v-on): Sử dụng để lắng nghe các sự kiện. Ví dụ:

<button @click="handleClick">Click me</button>
  • : (v-bind): Sử dụng để gán giá trị vào thuộc tính hoặc prop. Ví dụ:
<img :src="imageSrc" :alt="imageAlt">
  • # (v-slot): Sử dụng để làm việc với slots trong Vue. Ví dụ:
<template #header>
  <h1>Freetuts.net</h1>
</template>

Sử dụng các shorthand directive không chỉ giúp viết code ngắn gọn hơn mà còn tạo điều kiện cho tính nhất quán và dễ đọc, đồng thời làm tăng sự hiệu quả và dễ dàng trong việc bảo trì codebase. Đảm bảo rằng toàn bộ nhóm đều tuân thủ cách sử dụng này để tận dụng lợi ích của chúng.

10. Tách logic từ Template với Computed Properties trong VueJS 2

Tách biệt Logic phức tạp từ Template

Việc đặt nhiều logic hoặc tính toán phức tạp trực tiếp trong template có thể làm cho mã nguồn trở nên khó đọc và bảo trì. Điều này cũng làm giảm khả năng tái sử dụng của mã nguồn vì logic và template bị phụ thuộc vào nhau một cách rối rắm.

Lợi ich của việc sử dụng Computed Properties và cách thực hiện một cách hiệu quả

  • Tách biệt Logic: Sử dụng Computed Properties để thực hiện các tính toán phức tạp hoặc xử lý dữ liệu. Điều này giúp tách biệt logic ra khỏi template, tạo điều kiện cho mã nguồn dễ đọc và tái sử dụng hơn.

  • Hiệu quả và tối ưu: Computed Properties chỉ được tính toán lại khi các biến liên quan thay đổi. Điều này giúp cải thiện hiệu suất của ứng dụng vì không cần phải tính toán lại mọi thứ mỗi khi có sự kiện thay đổi.

Ví dụ:

<template>
  <div>
    <p>{{ fullName }}</p>
    <input v-model="firstName">
    <input v-model="lastName">
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: '',
      lastName: ''
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
};
</script>

Việc sử dụng Computed Properties như fullName ở trên giúp tính toán fullName chỉ khi firstName hoặc lastName thay đổi, giữ cho logic tính toán được tách biệt và hiệu quả.

Kết bài

Việc áp dụng những best practices trong VueJS 2 không chỉ là việc tối ưu hóa mã nguồn, mà còn là việc xây dựng nền tảng vững chắc cho dự án của bạn. Từ việc sử dụng các directive shorthand để làm cho code ngắn gọn và dễ đọc đến việc validate dữ liệu props để đảm bảo tính nhất quán và đáng tin cậy của ứng dụng, mỗi best practice đều đóng góp vào việc phát triển một ứng dụng VueJS mạnh mẽ.

Tuy nhiên, việc áp dụng những best practices không chỉ là điều cần thiết. Quan trọng hơn, việc duy trì và tuân thủ chúng qua mỗi giai đoạn của dự án là chìa khóa để xây dựng và duy trì một mã nguồn linh hoạt, dễ bảo trì và dễ mở rộng.

Hãy luôn nhớ rằng, việc thực hiện những best practices không chỉ là để tối ưu hóa mã nguồn một cách cụ thể. Nó còn là cách tiếp cận để xây dựng một cộng đồng phát triển vững mạnh, với mục tiêu chung là tạo ra những sản phẩm chất lượng và dễ bảo trì trong thời gian dài.

Cùng chuyên mục:

Bài tập VueJS 2: Sử dụng Axios hoặc Fetch API trong VueJS 2

Bài tập VueJS 2: Sử dụng Axios hoặc Fetch API trong VueJS 2

Bài tập VueJS 2: Two-way binding trong VueJS 2

Bài tập VueJS 2: Two-way binding trong VueJS 2

Bài tập VueJS 2: Xử lý sự kiện trong VueJS 2

Bài tập VueJS 2: Xử lý sự kiện trong VueJS 2

Bài tập VueJS 2: Components trong VueJS 2

Bài tập VueJS 2: Components trong VueJS 2

Bài tập VueJS 2: Binding dữ liệu trong VueJS 2

Bài tập VueJS 2: Binding dữ liệu trong VueJS 2

Sử dụng directives (v-bind, v-model) để hiển thị và cập nhật dữ liệu bằng VueJS 2

Sử dụng directives (v-bind, v-model) để hiển thị và cập nhật dữ liệu bằng VueJS 2

Tạo nút và xử lý sự kiện khi nút được nhấn trong VueJS 2

Tạo nút và xử lý sự kiện khi nút được nhấn trong VueJS 2

VueJS 2 Components: Tạo và quản lý ToDo List đơn giản

VueJS 2 Components: Tạo và quản lý ToDo List đơn giản

Các quy tắc trong VueJS 2

Các quy tắc trong VueJS 2

Tạo component và binding data trong VueJS 2

Tạo component và binding data trong VueJS 2

Tìm hiểu Scoped CSS trong VueJS 2

Tìm hiểu Scoped CSS trong VueJS 2

Sử dụng forceUpdate trong VueJS 2

Sử dụng forceUpdate trong VueJS 2

Sử dụng v-for trong VueJS 2

Sử dụng v-for trong VueJS 2

Các tạo Custom Directives trong VueJS 2

Các tạo Custom Directives trong VueJS 2

Sử dụng V-for và V-if trong VueJs 2

Sử dụng V-for và V-if trong VueJs 2

Sử dụng methods trong VueJS 2

Sử dụng methods trong VueJS 2

Khác nhau giữa slot và scoped slots trong VueJS 2

Khác nhau giữa slot và scoped slots trong VueJS 2

Tìm hiểu Slots trong VueJS 2

Tìm hiểu Slots trong VueJS 2

Xử lý Custom Events trong VueJS 2

Xử lý Custom Events trong VueJS 2

Ref và Reactive trong VueJS 2

Ref và Reactive trong VueJS 2

Top