Using Vuex modules: examples and best practices
In large-scale Vue.js single-page applications, as the number of components explodes and business logic becomes increasingly complex, maintaining a global Store (such as store/index.js) often proves difficult. At this point, introducing the Vuex Modules mechanism becomes a critical step in optimizing project architecture. This tutorial will deeply analyze how to define, register, and use Modules, demonstrating their core advantages and application scenarios through practical code examples.
What are Vuex Modules?
Vuex Modules allow us to split a large Store into multiple small, independent modules (Module). Each module can have its own state, getters, mutations, and actions, and even contain sub-Modules. This layered structure not only reduces code coupling but also improves team collaboration efficiency, allowing different developers to develop different business domains in parallel without interference.
Creating and Defining Modules
Create a new module folder under the src/modules directory, for example user.js. In this file, simply export the configuration object directly:
// src/modules/user.js
export default {
namespaced: true, // Enable namespace mode (recommended)
state() {
return {
userInfo: null,
token: ''
}
},
getters: {
isLoggedIn(state) {
return !!state.token;
}
},
mutations: {
SET_USER_INFO(state, info) {
state.userInfo = info;
},
CLEAR_TOKEN(state) {
state.token = '';
}
},
actions: {
login({ commit }, credentials) {
// Simulate login logic
const user = { name: 'Admin', role: 'admin' };
commit('SET_USER_INFO', user);
return Promise.resolve(user);
}
}
}
Registering Modules to the Store
Import and register this Module in src/store/index.js. After enabling namespaces, you must explicitly specify the module name:
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
appMode: 'dev' // Example of global state
},
mutations: {
SET_MODE(state, mode) {
state.appMode = mode;
}
},
actions: {
setAppMode({ commit }, mode) {
commit('SET_MODE', mode);
}
},
modules: {
user: require('./modules/user') // Register the user module, automatically enabling namespace
}
})
Using Modules in Components
Since namespaced: true is enabled, all operations must include the prefix (e.g., user/); otherwise, Vuex will throw an error. Here are three common usage methods:
Accessing State
this.$store.state.user.userInfo.name // ❌ Error this.$store.getters['user/isLoggedIn'] // ✅ CorrectTriggering Mutations
this.$store.commit('user/SET_USER_INFO', userData)Calling Actions
this.$store.dispatch('user/login', { username: 'test' }) // Supports asynchronous operations returning a Promise const result = await this.$store.dispatch('user/register', data); console.log(result.token);
Advanced Usage of Nested Modules
When business requirements demand finer-grained splitting, you can create sub-modules. For example, split user.js into profile.js and settings.js:
// src/modules/user/profile.js
export default {
namespaced: true,
state() {
return { avatarUrl: '' }
},
actions: {
updateAvatar({ commit }, url) {
commit('avatar/SET_AVATAR', url);
}
}
}
// src/modules/user/settings.js (same structure as above)...
Reference the sub-module in the parent module:
// src/modules/user.js
export default {
namespaced: true,
state() {
return { ...this.$store.state.user.profile.avatarUrl } // Access child state
},
modules: {
profile: require('./profile'),
settings: require('./settings')
}
}
Best Practices and Considerations
- Always enable namespaces: Avoid global pollution and ensure code readability.
- Single Responsibility Principle for Modules: Each Module should focus on a specific business domain (e.g., User, Product, Order).
- Keep State Flat: Try to retrieve deep data through computed properties or Actions to reduce nesting levels.
- Test First: It is more convenient to write unit tests for independent Modules, facilitating regression verification.
Through these practices, Vuex Modules can effectively support the scalability requirements of medium-to-large Vue projects, making state management both clear and efficient.