Theo dõi action trong NuxtJS

Khi làm việc với ReactJS trên kiến trúc dva mình có khái niệm là watcher effect , và khi làm việc với ứng dụng NuxtJS, cơ chế nào để mình có thể theo dõi action trong NuxtJS, với một user case là khi user login vào hệ thống (action là user/login), và login xong (tức là đã có thông tin về người dùng) thì mình sẽ theo dõi và thực hiện 1 thao tác khác là yêu cầu người dùng bật location của browser (tương ứng với action là user/requestLocation), thì chúng ta sẽ tiếp cận như thế nào trong NuxtJS

Để xử lý việc này đầu tiên, mình có các khái niệm cần nắm

  1. Cách sử dụng phương thức subscribe trong store
  2. Hiện thực mã để theo dõi được action

Cách sử dụng phương thức subscribe trong store

Xem qua cú pháp để xử dụng được store.subscribe trong NuxtJS mình phải tạo plugins và đăng ký nó, giả sử ở đây plugin mình đặt tên là watcher đường dẫn @/plugins/watcher.js

const myPlugin = (store) => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    // The mutation comes in the format of `{ type, payload }`.
  });
};

Sau khi tạo plugin xong, mình đăng ký plugins trong file nuxt.config.js, với mã bên dưới

Đăng ký plugin với ~plugins/watcher

Với cách này, hàm subscribe nó được gọi mổi mutation đợi gọi, mình sẽ không phân chia ra được là theo dõi được action lúc bắt đầu và kết thúc được (@@start, @@end), mà nó chỉ theo dõi mutation (tức là action đã hoàn thành và đẩy xuống cập nhật state mình mới bắt được nó). Như vậy mình sẽ không thể dựa vào subscribe để làm được việc này

Hiện thực mã để theo dõi được action

Theo dõi loại hàm tiện ích mình đã xây dựng ở bài trước https://luuxuantruong.info/quan-ly-trang-thai-tai-cua-side-effect-trong-nuxtjs/, với cách triển khai ở bài này mình đã quản lý được việc actions được gọi lúc bắt đầu và kết thử ở lớp view của ứng dụng, vậy làm sao để mình có thể áp dụng thêm được là theo dõi được action, để gọi và xử lý tiếp như trường hợp trên (khi mình quan sát được action là auth/login/@@end, lúc này đã có thông tin người dùng thì mình gọi tiếp 1 action khác để xử lý)

import { watchers } from '@/watchers'
export const callWithWaiter = store => async (actionName, payload) => {
  if (watchers[`${actionName}/@@start`]) {
    await watchers[`${actionName}/@@start`](store)
  }
  await store.dispatch('wait/start', actionName, { root: true })
  const response = await store.dispatch(actionName, payload)
  await store.dispatch('wait/end', actionName, { root: true })
  if (watchers[`${actionName}/@@end`]) {
    await watchers[`${actionName}/@@end`](store, response)
  }
  return (response && response.data) || null
}

Hàm tiện ích được mình cập nhật lại mã, ứng với hàm hàm này mình điều khiển được việc @@start@@end của các action

Việc đơn giản là giờ mình tạo thêm file @/watchers/index.js để khai báo các watcher cần thiết và gọi gì thì nó được gọi tới, tham khảo đoạn mã bên dưới của file @/watchers/index.js

export const watchers = {
  "auth/login/@@start": function ({ commit, ...rest }) {
    console.log("login start", rest);
  },
  "auth/login/@@end": function ({ commit }, response) {
    console.log("login end", response);
  },
};

Ứng với đoạn mã trên mình tạo 2 watchers là auth/login/@@startauth/login/@@end ứng với việc theo dõi action được bắt đầu và kết thúc, tham số của watcher là store. Với ‘@@end’ mình thêm tham số đầu vào là response nếu có để xử lý tiếp mà không cần thông qua store để truy cập kết quả hiện tại

Ở ví dụ trên mình đang tổng hợp tất cả watchers vào 1 file duy nhất cho nhanh, các bạn có thể phân chia ra theo từng module thì nhìn nó sẽ chuyên nghiệp hơn.

5/5 - (3 votes)

You May Also Like

About the Author: truongluu

Leave a Reply

Your email address will not be published. Required fields are marked *