Vue 3: Làm quen và sử dụng thử Composition API

Mở đầu

Chào các bạn, đã cũng đã lâu rồi không biết bài trở lại. Hôm nay mình đã trở lại rồi đây. Chắc các bạn cũng biết mình là một PHP/Laravel Dev vì vậy đối với mình VueJs là một JS Framework vô cùng quen thuộc. Tại sao lại quen thì nếu ai dùng Laravel từ lâu thì cũng hiểu rằng trước đây thì Laravel tích hợp sẵn VueJS và việc sử dụng nó vô cùng tiện lợi và dễ dàng (hiện tại có thêm option ReactJS nữa).

Phiên bản VueJS mà mình dùng từ trước đến nay là version 2. Bởi vì cũng đã quen dùng rồi nên mặc dù Vue 3 ra mắt cũng tương đối lâu ( khoảng cuối tháng 9 2020) thế nhưng mình cũng…lười nên chưa tìm hiểu về nó. Hôm nay chúng ta cùng làm quen và tìm hiểu về nó xem nó có những tính năng gì mới, đặc biệt và hay ho nhé.

Let’s get started!

Vue?

Tổng quan về Vue

Trước khi vào bài chính thì chúng ta cùng điểm qua một chút về Vue cho những ai chưa biết nhé.

  • Vue.js, gọi tắt là Vue (phát âm là /vjuː/, giống như view trong tiếng Anh), là một JS Framework dùng để xây dựng giao diện người dùng (UI), ứng dụng SPA (Single Page Application).
  • Vue được tạo ra bởi Evan You – một lập trình viên người Trung Quốc.
  • Phiên bản đầu tiên được release vào tháng 12 năm 2014.
  • Vue 3 được release chính thức vào 18/09/2020
  • Hiện tại Vue là 1 trong 3 JS Framework được ưa chuộng đối với các developer, 2 đối thủ còn lại là React và Angular.
  • Hiện tại Vue đang có số lượng star khá lớn ở trên Github là 183k (tính đến thời điểm bài viết này được public), nhiều hơn so với đối thủ ReactJS với 163k. Bạn có thể truy cập/contribute tại đây: https://github.com/vuejs/vue

Các tính năng mới đặc biệt trên Vue 3

  • Nhẹ hơn và nhanh hơn
  • Virtual DOM được cải tiến cho hiệu quả performance cao hơn
  • Tăng khả năng hỗ trợ Typescript.
  • Composition API
  • Teleport
  • Fragments (hay còn gọi là multiple root nodes)
  • Suspense

Trong bài hôm nay tạm thời chúng ta tìm hiểu về Composition API trước nhé.

Cài đặt Vue 3

Bạn có thể chọn 1 trong 4 cách dưới đây để cài đặt Vue 3 nhé:

Sử dụng CDN

Đơn giản thôi, chỉ cần cho đoạn code sau vào HTML:

<script src="https://unpkg.com/vue@next"></script>

Sử dụng npm

# latest stable
$ npm install vue@next

Sử dụng Vue CLI

Bạn có thể xem thêm ở trang chính thức của Vue: https://v3.vuejs.org/guide/installation.html#cli

Sử dụng Vite (khuyên dùng)

Các bạn chạy lệnh sau:

npm init @vitejs/app

Sau khi chạy lệnh trên thì các bạn chỉ cần bấm chọn 1 vài thông số như sau là được:

Sau đó các bạn chạy các lệnh mà terminal vừa hiện ra là bạn có ngay 1 demo như sau:

Composition API

Đặt vấn đề

chắc các bạn cũng biết Vue cho phép bạn tạo ra các components và mục đích của việc này là để cho ứng dụng của chúng ta trở lên dễ đọc hơn, tái sử dụng được nhiều code hơn, dễ maintain hơn,… Ngoài ra chắc các bạn cũng biết Vue cũng hỗ trợ các Lifecycle hooks (beforeCreate, created, beforeMount, mounted,…) hay là computed hoặc watcher để chúng ta dễ dàng xử lý, tương tác dữ liệu đúng không.

Ví dụ khi bạn làm chức năng hiển thị, filter danh sách các quyển sách theo người dùng chẳng hạn thì về cơ bản code sẽ như sau:

// template...

export default {
  props: {
    userId: {
      type: Number,
      required: true
    }
  },
  data () {
    return {
      books: [], 
      filters: { ... }, 
      searchQuery: ''
    }
  },
  computed: {
    filtered () { ... },
  },
  watch: {
    user: 'getBooks'
  },
  methods: {
    getBooks () {
    // Xử lý lấy books
    }, // 1
    filter () { ... },
  },
  mounted () {
    this.getBooks()
  }
}

Qua ví dụ trên các bạn có thể thấy rằng lúc này chúng ta sẽ phải phân tán code khắp nơi đúng không. Từ các lifecycle hooks đến computed hay watcher. Khi sửa thì phải kéo lên kéo xuống, kéo từ đầu file tới cuối file thực sự rất mệt mỏi (ví dụ khi đang sửa mouted mà phải sửa lại data thì kéo mệt nghỉ luôn). Việc phân tán này làm cho người đến sau tương đối mất thời gian để sửa code, hiểu logic.

Và thế là Composition API ra đời. Vậy nó giải quyết được gì? Có gì hay ho? Mời các bạn theo dõi tiếp bài viết.

Các tính năng của Composition API

Về cơ bản Composition API cung cấp cho bạn 1 thứ gọi là setup. Trong setup bạn có thể sử dụng được mọi thứ cần thiết của 1 component như Lifecycle hooks, computed, watcher,…

Tuy nhiên cần lưu ý: bởi vì setup được chạy trước khi component được created nên là bạn sẽ không thể dùng được this bên trong nó đâu nhé. Điều đó có nghĩa là bạn không thao tác được với data hay method được khai báo bên ngoài. Tuy nhiên, bạn vẫn có thể sử dụng được props bên trong setup nhé.

Chúng ta có 1 ví dụ nhỏ như sau:

<template>
  <h1>{{ count }}</h1>
  <button @click="click">Click here</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup (props) {
    const count = ref(0)

    const click = () => {
      count.value++;
    }

    return {count, click};
  },
  watch: {
    count(value) {
      console.log(value);
    }
  }
}
</script>

Chúng ta sẽ cùng phân tích 1 chút nhé, đây là ví dụ khi click vào button thì số sẽ nhảy theo lượt click.

Bên trong function setup ta thấy có count = ref(0) đúng không, đây là các bạn đang khởi tạo 1 biến reactive thông qua function ref và đặt giá trị ban đầu cho nó là 0.

Tiếp theo mình sẽ có 1 biến tên là click được gán 1 function vào và khi gọi thì value của count bên trên sẽ được tăng lên . Sau đó thì return về 2 biến mình cần.

Sau khi return về thì các bạn có thể thao tác với count – giống như data và click – giống như method vậy.

Như vậy vẫn chưa hết thú vị đâu, bên trong setup chúng ta còn có thể sủ dụng được Lifecycle hooks nữa đó.

import { ref, onMounted, onCreated } from 'vue'  

// component
setup (props) {
    const callAPI = () => {
    }
    
    onMounted(callAPI);
    onCreated(callAPI);
    // Chỉ cần thêm on + hooks phía sau

    return {callAPI};
  },

Còn cả watch và nữa

import { ref, computed, watch } from 'vue'  

// component
setup (props) {
    const count = ref(0)

    const click = () => {
      count.value++;
    }

    watch(count, () = > {
        console.log(const.value);
    });

    const doubleClick = computed(() => {
        return click * 2;
    });

    return {count, click, doubleClick};
  },

Các bạn có thấy xịn sò không. Như vậy, lúc này chúng ta có thể refactor lại đoạn code lúc đầu như sau để dễ dàng maintain hơn.

import { ref, computed, watch } from 'vue'

export default {
  props: {
    userId: {
      type: Number,
      required: true
    }
  },
  setup(props) {
    // List books
    const books = ref([]);
    const filters = ref({ ... })
    const filtered = computed(books, () => { ... });
    const getBooks = () => {
      // Xử lý lấy books
    }
    const filter = () => { ... };
    // hooks
    watch(user, getBooks);
    onMounted(getBooks);

    // Create book
    ...
    watch(book, () => { ... });
    onMounted(getUser);
    ...

    return {
        books,
        filters,
        filtered,
        filter
    }
  }
}

Lúc này bạn có thể thấy rằng code được tập chung thành 1 khối rất rõ ràng đúng không nhỉ. Lúc này các bạn hoàn toàn có thể tách ra thành các file để cho setup trở lên clear hơn kiểu như sau:

// ListBooks.js

export default function ListBooks {
    // List books
    const books = ref([]);
    const filters = ref({ ... })
    const filtered = computed(books, () => { ... });
    const getBooks = () => {
      // Xử lý lấy books
    }
    const filter = () => { ... };

    return {
        books,
        filters,
        filtered,
        filter
    }
}

// Trong component
// ListBooks.js

import ListBooks from ListBooks.js;

export default {
  props: {
    userId: {
      type: Number,
      required: true
    }
  },
  setup(props) {
    {
        books,
        filters,
        filtered,
        filter
    } = ListBooks();

    // Create book
    ...
    

    return {
        books,
        filters,
        filtered,
        filter
    }
  }
}

Kết luận

Qua bài viết này bạn có thể thấy rằng Vue 3 thực sự đã được cải tiến hơn nhiều so với Vue 2 và Composition API là một tính năng mới lạ và cũng hứa hẹn nhiều hiệu quả nữa. Ở bài sau mình sẽ viết về những tính năng thú vị khác của Vue 3 nhé.

Hẹn gặp lại các bạn trong bài viết sau!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *