- vừa được xem lúc

Sử dụng Vuex để quản lý state trong VueJS

0 0 39

Người đăng: Ngoan Nguyen

Theo Viblo Asia

Nếu bạn đã từng phát triển ứng dụng single page có quy mô lớn, thì có thể bạn sẽ biết tới khái niệm quản lý trạng thái (state management), Như là Flux, được phát bởi Facebook thông qua Redux.

Thì trong bài viết này mình sẽ hướng dẫn pattern trên trong VueJS sử dụng VueX

Cài đặt

Vuex, bạn có thể cài thông qua yarn hoặc npm.

# Yarn
$ yarn add vuex
# NPM
$ npm install vuex --save

Sau đó, phải enable Vuex plugin trong ứng dụng Vue của bạn.

main.js
======================================= import Vue from 'vue';
import Vuex from 'vuex';
import App from 'App.vue'; Vue.use(Vuex); new Vue({ el: '#app', render: h => h(App)
});

Khởi tạo Store

Để có thể sử dụng những tính năng hay ho của Vuex, đầu tiên bạn phải tạo 1 global store object.

Nó không thể được truy cập hoặc sửa đổi trực tiếp để đảm bảo trạng thái nhất quán và cho phép theo dõi các thay đổi.

store.js
====================================== export const store = new Vuex.Store({ state: { safelyStoredNumber: 0 }
});

Bây giờ, để access tới Store, bạn sẽ phải import nó vào tất cả các components hoặc có thể đưa nó vào file main.js để tự động import cho mọi components khác trong ứng dụng.

main.js
======================================= import Vue from 'vue';
import Vuex from 'vuex';
import App from 'App.vue';
import { store } from './store.js'; Vue.use(Vuex); new Vue({ store, el: '#app', render: h => h(App)
});

Getters

Chắc ai cũng biết đến Getter, nó sẽ lấy các giá trị của state trong Store. Trong components, nó có thể được truy cập thông qua $$store.getters.property như là 1 thuộc tính, không phải là một hàm. Nếu getter cần một tham số, nó có thể trả về một hàm thứ hai nhận tham số.

store.js
===================================== export const store = new Vuex.Store({ state: { safelyStoredNumber: 0 }, getters: { safelyStoredNumber: state => state.safelyStoredNumber, storedNumberMatches(state) { return matchNumber => { return state.safelyStoredNumber === matchNumber; } } // Cách ngắn gọn hơn: // storedNumberMatches: state => matchNumber => state.safelyStoredNumbers === matchNumber }
});

Tuy nhiên, cách dễ dàng để truy cập vào các getters trong components của bạn là thông qua phương thức mapGetters của Vuex. Điều này cho phép bạn gắn getters vào các thuộc tính ở mức cao nhất trong component của bạn.

App.vue
========================================= <template> <p>The safely stored number: {{safelyStoredNumber}}<p>
</template> <script>
import { mapGetters } from 'vuex' export default { computed: { ...mapGetters([ 'safelyStoredNumber' ]) }
}
</script>

Thay đổi State

Mutations

Cách duy nhất để có thể thay đổi state trong Vuex là bằng cách “commit” một sự thay đổi. Vuex mutation tương tự như là event: mỗi một thay đổi có có type và handler.

Chúng ta có thể sử dụng this.$store.commit(‘mutationName’, payload).

store.js
======================================= export const store = new Vuex.Store({ state: { safelyStoredNumber: 0 }, ... mutations: { incrementStoredNumber(state) { state.safelyStoredNumber++; }, setStoredNumber(state, newNumber) { state.safelyStoredNumber = newNumber; } }
});

Như getters, Vuex cũng có một phương thức tiện lợi cho các mutations trong component, mapMutations helper method. Nó cho phép bạn mount các mutations dưới dạng các phương thức trong component.

App.vue
======================================================= <template> <p>The safely stored number: {{safelyStoredNumber}}<p>
</template> <script>
import { mapMutations } from 'vuex' export default { ... methods: { ...mapMutations([ // "incrementStoredNumber" mutation thành `this.incrementStoredNumber()`. 'incrementStoredNumber', // "setStoredNumber" mutation thành `this.setStoredNumber(newNumber)`. 'setStoredNumber' ]) }
}
</script>

Asynchronous Actions

Tương tự như với mutation nhưng có một vài khác biệt. Action là hoạt động bất đồng bộ (asynchronous) còn mutations là hoạt động đồng bộ (synchronous). Do Vuex học tập thiết kế luồng dữ liệu một chiều (one way data flow) từ các hệ thống như Flux, Redux … do đó mutations là các hoạt động đồng bộ và một chiều để thay đổi dữ liệu state. Actions thường là nơi chứa các hành động như lấy dữ liệu từ API hay một hành động làm thay đổi dữ liệu trong CSDL (thêm, sửa, xóa)

Actions được sử dụng trong các components: this.$ store.dispatch(‘actionName’, payload).then(response => {}).

Để thay đổi state trong action sử dụng context.commit(‘mutationName’, payload).

store.js
============================================== import myRemoteService from './my-remote-service.js' export const store = new Vuex.Store({ state: { safelyStoredNumber: 0 }, ... actions: { async setNumberToRemoteValue(context) { context.commit('setStoredNumber', await myRemoteService.getRemoteValue()); return Promise.resolve(); }, }
}); 

Phương thức đối với các actions, (có thể được gọi là mapActions) được sử dụng giống như mutations.

<template> <p>The safely stored number: {{safelyStoredNumber}}<p>
</template> <script>
import { mapActions } from 'vuex' export default { ... methods: { ...mapActions([ // Mount action "setNumberToRemoteValue" thành `this.setNumberToRemoteValue()`. 'setNumberToRemoteValue', ]) }
}
</script>

Module hóa

Vì là Vuex sử dụng một cây state nên tất cả state của ứng dụng dược chứa đựng bên trong một đối tượng lớn. Tuy nhiên khi mà ứng dụng mở rộng lên thì kho chứa (store) có thể phình lên rất nhiều. Để giải quyết vấn đề này, Vuex cho phép chúng ta chia nhỏ những store ra trong module. Mỗi module đều có thể chứa đựng states, mutations, actions, getters hay cả những module lồng nhau.

my-store-module.js
====================================== export const myModule = { namespaced: true, state: { myModularizedNumber: 0 }, getters: { myModularizedNumber: state => state.myModularizedNumber }, mutations: { setModularizedNumber(state, newNumber) { state.myModularizedNumber = newNumber } }
}
store.js
====================================== import { myModule } from './my-store-module.js'; export const store = new Vuex.Store({ modules: { myModule }, state: { safelyStoredNumber: 0 }, ...
});

Bạn có thể lồng các modules trong modules. Ngoài ra, mapGetters, mapMutations và mapActions tất cả sẽ lấy tham số đầu tiên để làm module namespace, để tránh viết code như bên dưới:

...mapGetters([ 'myModule/nestedModule/subNestedModule/exampleGetter', 'myModule/nestedModule/subNestedModule/anotherGetter',
])

Và đây là cách viết khác:

...mapGetters('myModule/testedModule/subNestedModule', [ 'exampleGetter', 'anotherGetter'
])

Hy vọng là bài viết này sẽ giúp các bạn hiểu hơn về state management sử dụng Vuex!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 525

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 396

- vừa được xem lúc

Đặt tên commit message sao cho "tình nghĩa anh em chắc chắn bền lâu"????

. Lời mở đầu. .

1 1 737

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 358

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 449

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 433