Trong quá trình phát triển ứng dụng Vuejs, việc lấy dữ liệu từ máy chủ là một phần quan trọng và không thể thiếu. Tại Cafedev, chúng tôi hiểu rằng việc sử dụng Vue Router kết hợp với việc lấy dữ liệu là một phần không thể tách rời trong quá trình xây dựng ứng dụng web động. Bài viết này sẽ hướng dẫn bạn cách thực hiện việc này một cách hiệu quả, từ việc lấy dữ liệu sau khi điều hướng đến việc lấy dữ liệu trước khi điều hướng. Hãy cùng khám phá chi tiết qua bài viết dưới đây!

Đôi khi bạn cần lấy dữ liệu từ máy chủ khi một tuyến đường được kích hoạt. Ví dụ, trước khi hiển thị hồ sơ người dùng, bạn cần lấy dữ liệu người dùng từ máy chủ. Chúng ta có thể đạt được điều này theo hai cách khác nhau:
Lấy Sau Khi Điều Hướng: thực hiện điều hướng trước và lấy dữ liệu trong vòng đời của thành phần đến. Hiển thị trạng thái đang tải trong khi dữ liệu đang được lấy.
Lấy Trước Khi Điều Hướng: Lấy dữ liệu trước khi điều hướng trong bộ bảo vệ nhập tuyến, và thực hiện điều hướng sau khi dữ liệu đã được lấy.
Về mặt kỹ thuật, cả hai đều là lựa chọn hợp lệ – điều quan trọng là phụ thuộc vào trải nghiệm người dùng mà bạn đang nhắm đến.

1. Lấy Sau Khi Điều Hướng

Khi sử dụng cách tiếp cận này, chúng ta điều hướng và hiển thị ngay lập tức thành phần đến, và lấy dữ liệu trong chính thành phần đó. Điều này cho phép chúng ta hiển thị trạng thái đang tải trong khi dữ liệu đang được lấy qua mạng, và chúng ta cũng có thể xử lý việc tải khác nhau cho mỗi chế độ xem.
Hãy giả sử chúng ta có một thành phần Post cần lấy dữ liệu cho một bài đăng dựa trên route.params.id:

code-group

[Composition API]
  <div class="post">
    <div v-if="loading" class="loading">Loading...</div>

    <div v-if="error" class="error">{{ error }}</div>

    <div v-if="post" class="content">
      <h2>{{ post.title }}</h2>
      <p>{{ post.body }}</p>
    </div>
  </div>

<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { getPost } from './api.js'

const route = useRoute()

const loading = ref(false)
const post = ref(null)
const error = ref(null)

// watch the params of the route to fetch the data again
watch(() => route.params.id, fetchData, { immediate: true })

async function fetchData(id) {
  error.value = post.value = null
  loading.value = true
  
  try {
    // replace `getPost` with your data fetching util / API wrapper
    post.value = await getPost(id)  
  } catch (err) {
    error.value = err.toString()
  } finally {
    loading.value = false
  }
}
</script>
[Options API]
  <div class="post">
    <div v-if="loading" class="loading">Loading...</div>

    <div v-if="error" class="error">{{ error }}</div>

    <div v-if="post" class="content">
      <h2>{{ post.title }}</h2>
      <p>{{ post.body }}</p>
    </div>
  </div>

<script>
import { getPost } from './api.js'

export default {
  data() {
    return {
      loading: false,
      post: null,
      error: null,
    }
  },
  created() {
    // watch the params of the route to fetch the data again
    this.$watch(
      () => this.$route.params.id,
      this.fetchData,
      // fetch the data when the view is created and the data is
      // already being observed
      { immediate: true }
    )
  },
  methods: {
    async fetchData(id) {
      this.error = this.post = null
      this.loading = true

      try {
        // replace `getPost` with your data fetching util / API wrapper
        this.post = await getPost(id)
      } catch (err) {
        this.error = err.toString()
      } finally {
        this.loading = false
      }
    },
  },
}
</script>

2. Lấy Trước Khi Điều Hướng

Với cách tiếp cận này, chúng ta lấy dữ liệu trước khi thực sự điều hướng đến tuyến đường mới. Chúng ta có thể thực hiện việc lấy dữ liệu trong bộ bảo vệ beforeRouteEnter trong thành phần đến, và chỉ gọi next khi việc lấy dữ liệu hoàn tất. Hàm gọi lại được truyền vào next sẽ được gọi sau khi thành phần được gắn kết:

export default {
  data() {
    return {
      post: null,
      error: null,
    }
  },
  async beforeRouteEnter(to, from, next) {
    try {
      const post = await getPost(to.params.id)
      // `setPost` is a method defined below
      next(vm => vm.setPost(post))
    } catch (err) {
      // `setError` is a method defined below
      next(vm => vm.setError(err))
    }
  },
  // when route changes and this component is already rendered,
  // the logic will be slightly different.
  beforeRouteUpdate(to, from) {
    this.post = null
    getPost(to.params.id).then(this.setPost).catch(this.setError)
  },
  methods: {
    setPost(post) {
      this.post = post
    },
    setError(err) {
      this.error = err.toString()
    }
  }
}

Người dùng sẽ tiếp tục ở chế độ xem trước đó trong khi tài nguyên đang được lấy cho chế độ xem đến. Do đó, nên hiển thị thanh tiến trình hoặc một loại chỉ báo nào đó trong khi dữ liệu đang được lấy. Nếu việc lấy dữ liệu thất bại, cũng cần hiển thị một loại thông báo cảnh báo toàn cầu.

Qua bài viết này, chúng ta đã thấy rằng việc kết hợp Vue Router với việc lấy dữ liệu là một phần quan trọng của quá trình phát triển ứng dụng Vuejs. Tại Cafedev, chúng tôi luôn khuyến khích các nhà phát triển tận dụng tối đa các tính năng mạnh mẽ của Vuejs để xây dựng các ứng dụng web động và mạnh mẽ. Hy vọng rằng thông qua bài viết này, bạn đã có được những kiến thức bổ ích và cụ thể để áp dụng vào dự án của mình. Hãy tiếp tục theo dõi Cafedev để cập nhật thêm nhiều thông tin hữu ích khác!

Tham khảo thêm: MIỄN PHÍ 100% | Series tự học Vuejs từ cơ bản tới nâng cao

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của CafeDev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!