Tìm hiểu về Composition API trong Vue 3

Tìm hiểu về Composition API trong Vue 3
  • Vào Quý 1 năm 2020, đội ngũ của Vue đã giới thiệu Composition API. Nó được coi như một phần định hướng cốt lõi Vue 3 và giải quyết những hạn chế mà Option API truyền thống đã gặp phải. Trong bài viết này chúng sẽ đi tìm hiểu xem lợi ích của Composition API so với Option API và đặc điểm cơ bản của nó.

1. Code được sắp xếp theo các logic

export default {
  name: 'MyComponent',
  components: { ... },
  props: { ... },
  data() { return { ... } },
  computed: {},
  mounted() { ... }
  methods: {}
}
  • Đối với Option API như trên, các logic code sẽ bị phân tán vào các option (data, computed, methods, watch ...). Chúng gần như đáp ứng được mọi thứ ta cần trong lúc làm việc. Tuy nhiên khi các components trở lên lớn hơn và phức tạp hơn, để đọc hiểu cũng như sửa code, chúng ta sẽ phải sẽ phải di chuyển giữa các option, kéo liên tục lên xuống trong file. Làm việc này sẽ gây tốn thời gian, khó kiểm soát và cuối cùng là mệt mỏi vô cùng khi file của chúng ta lên tới hàng trăm dòng.
<script setup>
import { ref, reactive, computed } from 'vue';

// presentation
const salute = ref('Hello world');
const persona = reactive({
  name: 'Jesus Guerrero',
  age: 25
});
const greeting = computed(() => {
   return `${salute.value}, I am ${persona.name} and have ${persona.age} years old`.
});


// interests
const interest = reactive({
  searchText: "",
  list: ['javascript', 'hashnode', 'vue', 'vue3', 'laravel', 'supabase', 'productivity'],
});

const executeSearch = (searchText, list) => {
  let filteredList = list;
  if (searchText) {
    filteredList = list.filter((item) =>
      item.includes(searchText.toLowerCase())
    );
  }
  return filteredList;
};

const filteredInterest = computed(() => {
  return executeSearch(interest.searchText, interest.list);
});

return { greeting, filteredInterest };

</script>
  • Đối với Composition API như trên, thay vì chia thành các option, chúng ta chỉ cần sử dụng tag <script setup>, từ đó chúng ta có thể nhóm lại những logic lại với nhau. Ở đây chúng ta có thể thấy rằng phần logic của presentationinterests đã được nhóm lại, khiến chúng dễ dàng đọc hiểu và xử lý hơn.

2. Tương thích tốt hơn với TypeScript

<script lang="ts" setup >
import { ref, reactive, computed } from 'vue';
...
// interests
const interest = reactive({
  searchText: "",
  list: ['javascript', 'hashnode', 'vue', 'vue3', 'laravel', 'supabase', 'productivity'],
});

const executeSearch = (searchText: string, list: string[]): string[] => {
  let filteredList = list
  if (searchText) {
    filteredList = list.filter((item) =>
      item.includes(searchText.toLowerCase())
    );
  }
  return filteredList;
};

const filteredInterest = computed(() => {
  return executeSearch(interest.searchText, interest.list);
});
</script>
  • Sự hỗ trợ của TypeScript đối với Option API luôn luôn là điểm hạn chế cố hữu từ lâu do chúng ta phải quá phụ thuộc vào các magic của Vue. Thay vào đó, đối với Composition API, chúng ta sẽ viết lại một cách gần gũi hơn với JavaScript thuần bằng cách sử dụng các hàm và khiến cho chúng ta dễ dàng kiểm soát hơn.

3. Phân tách và tái tổ hợp code tốt hơn

  • Đối với Option API chúng ta bị giới hạn trong phạm vi của Vue Component, và từ đó cần phải sử dụng đến mixin và slot rất dài dòng. Nhưng đối với Composition API, chúng ta có thể tách được các hàm ra và tái sử dụng chúng theo cách ta muốn một cách dễ dàng.
// useSearch.ts
import { computed, Ref } from "vue"

export const useSearch = (searchText: Ref<string>, list: Ref<string[]>) => {
    const executeSearch = (searchText: string, list: string[]): string[] => {
        let filteredList: string[] = list
        if (searchText) {
          filteredList = list.filter((item) =>
            item.includes(searchText.toLowerCase())
          );
        }

        return filteredList;
    };

    const filteredList = computed(() => {
        return executeSearch(searchText.value, list.value);
    });

    return {
        filteredList
    }
} 
  • Như ví dụ trên, chúng ta extract hàm useSearch. Đối số của hàm useSearch chúng ta để là dạng ref, để chúng ta có thể reactivity giá trị của filteredList mỗi chúng ta tìm kiếm hoặc thêm một ngôn ngữ mới vào danh sách.
<script setup lang="ts">
import { reactive, toRefs } from "vue";
import { useSearch } from "../../utils/useSearch";

const interest = reactive({
  searchText: "",
  list: ['javascript', 'hashnode', 'vue', 'vue3', 'laravel', 'supabase', 'productivity'],
});

const { searchText, list } = toRefs(interest);
const { filteredList: filteredInterest } = useSearch(searchText, list);
</script>
  • Ở component khác cần tái sử dụng hàm useSearch, chúng ta có thể import và sử dụng chúng như những hàm thông thường trong JavaScript.

Kết luận

  • Vue 3 và Compostion API đưa đến cho chúng ta một cách tổ chức code linh hoạt, giảm phân mảnh các logic và dễ dàng tái sử dụng hơn. Việc sử dụng Composition API trong Vue 3 là không bắt buộc, mọi người vẫn có thế sử dụng Option API hoặc kết hợp chúng lại với nhau tùy theo yêu cầu của bài toán. Hi vọng bài viết này sẽ đưa cho bạn một cái nhìn tổng quan nhất.

Tài liệu tham khảo