Web Front-end
Vue.js
Easy to understand! Detailed explanation of VUEX state warehouse management
Easy to understand! Detailed explanation of VUEX state warehouse management
Vuex is a state management pattern developed specifically for Vue.js applications. It uses centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable way. To put it simply: when the application encounters multiple components sharing state, use vuex.
VueX is a state management framework specially designed for Vue.js applications, which uniformly manages and maintains the changeable state of each vue component
Scenario: multiple components share data or pass it across components Data time
Five core concepts of vuex:
- State: shared state, the basic data of vuex, used to store variables, equivalent to the data in the component data, except this becomes a global variable.
- Getter: Derived state based on state, equivalent to the computed properties in the component.
- Mutation: A method to change the shared state of the store in vuex, modify the state by submitting a mutation, and operate the data synchronously. It is usually used for actions to obtain asynchronous data, obtain data submitted to the mutation through commit, and operate synchronously in the mutation. data in state.
- action: Supports asynchronous operations, which can be used to asynchronously obtain the data in the request, and submit the obtained data to mutation synchronously to implement ajax asynchronous request for data, and mutation will synchronize its data to the state.
- modules: Modular vuex, in order to facilitate later project management, each module can have its own state, mutation, action, getters, making the structure very clear and easy to manage.
What are the advantages and disadvantages?
The main advantage is that data and methods can be shared globally. Convenient for unified management
Disadvantage: state variables will be restored and cleared after the page is refreshed, and will not be stored persistently like cookies.
How to solve the loss of vuex state data after the page is refreshed?
Let’s first talk about why it is lost?
Because the data in the store is stored in the running memory, when the page is refreshed, the page will reload the vue instance, and the data in the store will be reassigned.
How to avoid it?
In fact, it mainly depends on the usage scenario. If you want to retain certain data persistently, you can also use cookies or localStorage. For example, some login information, etc.
For example, after requesting the login information, you can first store it in localStorage, bind the variable value in the state to the one in the sessionStorage, and modify the state and localStorage at the same time when modifying the mutations. The final page uses variables in vuex directly. [Related recommendations: vue.js video tutorial]
Formally enter the installation using
vuex
Open the terminal and enter the command line npm install vuex - -save to download vuex
vuex application core management warehouse build store
Create a new store folder here, create a js named index.js,
In the index, by changing the state ,mutations, actions, and getters are introduced into the ,store and expose the store object.
The following is the code of index.js
/*
vuex最核心的管理对象 store
*/import Vue from 'vue';import Vuex from 'vuex';
// 分别引入这四个文件 这四个文件的内容和用法在下面分别讲到import state from './state';import mutations from './mutations';import actions from './actions';import getters from './getters';
//声明使用插件Vue.use(Vuex)//new 一个Vuex的对象,将state,mutation,action,getters配置到vuex的store中,方便管理数据export default new Vuex.Store({
state,
mutations,
actions,
getters,})Mount the store to the vue instance
In main.js
import store from './store'// ..........new Vue({
el: '#app',
router,
store, // ***
render: h => h(App)})state state management data
We usually put the shared data that needs to be managed into the state, making it look like a global variable, and introduce the state data to the required components.
const state = {
userId: '',
token: '',
name: '',
avatar: '',
introduction: '',
roles: [],
tenantId: 1,
userInfo: null};mutations Submit data synchronously
mutations are used to change the state logic in the state, and change the state data in the state synchronously.
What you need to know is that the state object can only be modified through mutations in vuex.
You can modify the state by getting the data obtained from actions, or you can directly define methods in the mutations module to change the state data.
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token;
},
SET_USERID: (state, userId) => {
state.userId = userId;
},
SET_NAME: (state, name) => {
state.name = name;
},
SET_ROLES: (state, roles) => {
state.roles = roles;
},
SET_TENANTID: (state, roles) => {
state.tenantId = roles;
},
SET_USER_INFO: (state, userInfo) => {
state.userInfo = userInfo;
}};Through mutations and the actions module below, you can also see that commit is used to call the mutation module.
The code for calling its mutation module in the component is:
this.$store.commit('SET_TOKEN', token_data)
Asynchronous operations of actions
actions are similar to their mutations, but they can perform asynchronous operations,
and will operate asynchronously The obtained data is submitted to mutations, causing mutations to change the state data in the state. This is often used to obtain data in ajax requests (because it is asynchronous), and commit the obtained data to mutations to update the state data status. The difference between
and mutations is that
- Action submits a mutation instead of directly changing the state.
- Action can contain any asynchronous operation.
For example
/* 下面就是通过actions执行异步Ajax请求,
得到数据后,
通过commit的方法调用mutations 从而更新数据
例如: commit('SET_TOKEN', data.uuid);
*/const actions = {
login({ commit }, userInfo) { // 用户登录
const params = userInfo;
params.userName = userInfo.userName.trim()
return new Promise((resolve, reject) => {
getLogin(params)
.then((response) => {
const { status, message, data } = response || {};
if (status === 200) {
// 存入 参数: 1.调用的值 2.所要存入的数据
commit('SET_USER_INFO', data);
commit('SET_TOKEN', data.uuid);
commit('SET_USERID', data.id);
commit('SET_ROLES', data.roles);
commit('SET_NAME', data.realName);
commit('SET_TENANTID', data.tenantId || 1);
setToken(data.uuid);
db.save('userInfo', data);
db.save('tenantId', data.tenantId || 1);
localStorage.setItem('loginToken', data.uuid);
resolve(data);
} else {
// ElementUI.Message.error(message); // axios拦截统一提示了
}
})
.catch((error) => {
// ElementUI.Message.error(error.message); // axios拦截统一提示了
reject(error);
});
});
},}The calling method of this actions in the component is:
this.$store.dispatch('user/login', postUser)
.then(res => {
// .............
})// 我这里的login方法写在了user.js这个module里 所以这里调用是 user/login// 下面会讲到moduleGetters process the state
Getters are quite For computed properties, it is used to process state data. It has two default parameters. The first default parameter is state, and the second default parameter is getters.
const getters={
plusCount(state){
return state.count + 1
},
//获取state中状态数据对象,和获取getters模块中plusCount数据
totalCount(state,getters){
return getters.plusCount + state.count }}The code snippet for calling this method in the component is:
this.$store.getters.totalCount()
Get the Vuex status in the Vue component
Read from the store instance The simplest way to state is to return a certain state in a calculated property. Since Vuex's state storage is responsive, whenever store.state.count changes here , the calculated attributes will be re-calculated and updated responsively.
computed: {
count: function(){
return this.$store.state.count }
},那么对于以上的store我们就简单介绍完了,相信大家看完后对于vuex会有一定的理解。那么这个时候我们要想,是不是使用this.$store.state或this.$store.getters.xxx感到麻烦呢?下面我们介绍另一种引入state和getters的方式
辅助函数 mapState 和 mapGetters
对于上述的在组件中引用state和getters的方法是不是感到麻烦呢?使用mapState你将会感受到便利。
组件中这样使用
//首先我们需要先将辅助函数引入import { mapGetters,mapState } from 'vuex'
export default {
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters( ['plusCount','totalCount'] )
// 使用对象展开运算符将 state 混入 computed 对象中
...mapState( ['userInfo','count'] )
},methods:{
getData(){
// 这里就能直接使用了 直接使用state 和getters里的数据
// this.userInfo
// this.plusCount
}}}Module子模块化管理
store文件夹下的index.js代码如下
import Vue from 'vue'import Vuex from 'vuex'import getters from './getters'Vue.use(Vuex)const modulesFiles = require.context('./modules', true, /\.js$/)const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules}, {})const store = new Vuex.Store({
modules,
getters})export default store文件目录如图

举例 api.js
import { getKey, getLogin, logout, getInfo } from '@/api/user';import { setToken, removeToken } from '@/utils/auth';import db from '@/utils/localstorage';import router, { resetRouter } from '@/router';import ElementUI from 'element-ui';const state = {
userId: '',
token: '',
name: '',
avatar: '',
introduction: '',
roles: [],
tenantId: 1,
userInfo: null
// roles: ['9999']};const mutations = {
SET_TOKEN: (state, token) => {
state.token = token;
},
SET_USERID: (state, userId) => {
state.userId = userId;
},
SET_NAME: (state, name) => {
state.name = name;
},
SET_ROLES: (state, roles) => {
state.roles = roles;
},
SET_TENANTID: (state, roles) => {
state.tenantId = roles;
},
SET_USER_INFO: (state, userInfo) => {
state.userInfo = userInfo;
}};const actions = {
// 获取密钥
getKey({ commit }) {
return new Promise((resolve, reject) => {
getKey()
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error);
});
});
},
// 用户登录
login({ commit }, userInfo) {
// const { username, password } = userInfo;
const params = userInfo;
params.userName = userInfo.userName.trim()
return new Promise((resolve, reject) => {
// console.log(username, password);
// setToken(state.token)
// localStorage.setItem('loginToken', state.token)
getLogin(params)
// getLogin({ userName: username.trim(), password: password })
.then((response) => {
const { status, message, data } = response || {};
if (status === 200) {
// 存入 参数: 1.调用的值 2.所要存入的数据
commit('SET_USER_INFO', data);
commit('SET_TOKEN', data.uuid);
commit('SET_USERID', data.id);
commit('SET_ROLES', data.roles);
commit('SET_NAME', data.realName);
commit('SET_TENANTID', data.tenantId || 1);
setToken(data.uuid);
db.save('userInfo', data);
db.save('tenantId', data.tenantId || 1);
localStorage.setItem('loginToken', data.uuid);
resolve(data);
} else {
// ElementUI.Message.error(message); // axios拦截统一提示了
}
})
.catch((error) => {
// ElementUI.Message.error(error.message); // axios拦截统一提示了
reject(error);
});
});
},
// 获取用户信息
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token)
.then((response) => {
const { data } = response;
data.roles = response.data.rights.map(String);
if (!data) {
reject('验证失败,请重新登录。');
}
const loginMessage = {
memberId: data.id,
userName: data.name,
userTel: data.mobile,
realName: data.realName,
incorCom: data.incorCom,
virtualCor: data.virtualCor,
deptId: data.deptId,
deptpath: data.deptpath,
deptName: data.deptName };
localStorage.setItem('loginMessage', JSON.stringify(loginMessage));
const { id, roles, realName } = data;
// 角色必须是非空数组!
if (!roles || roles.length <= 0) {
reject('getInfo: 角色必须是非空数组!');
}
commit('SET_USERID', id);
commit('SET_ROLES', roles);
commit('SET_NAME', realName);
localStorage.setItem('userRights', roles);
// commit('SET_AVATAR', avatar)
// commit('SET_INTRODUCTION', introduction)
resolve(data);
})
.catch((error) => {
reject(error);
});
});
},
// 用户登出
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token)
.then(() => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
db.remove('router');
removeToken();
resetRouter();
resolve();
})
.catch((error) => {
reject(error);
});
});
},
// 删除token
resetToken({ commit }) {
return new Promise((resolve) => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
removeToken();
resolve();
});
},
// 动态修改权限
changeRoles({ commit, dispatch }, role) {
return new Promise(async(resolve) => {
const token = role + '-token';
commit('SET_TOKEN', token);
setToken(token);
const { roles } = await dispatch('getInfo');
console.log(roles, 'rolesrolesroles');
resetRouter();
// 根据角色生成可访问路由映射
const accessRoutes = await dispatch('permission/generateRoutes', roles, {
root: true
});
// 动态添加可访问路由
router.addRoutes(accessRoutes);
// 重置已访问视图和缓存视图
dispatch('tagsView/delAllViews', null, { root: true });
resolve();
});
}};export default {
namespaced: true,
state,
mutations,
actions};这样后可以按功能分module使用
页面中调用就是
// 使用mutationsthis.$store.commit('api/SET_T', keys);// 使用actionsthis.$store.dispatch('user/login', postUser).then(res => {})// 如果没有分module // 那就是 this.$store.commit('SET_T', keys);// 直接调用方法写完自己也感觉好简单噢(⊙-⊙)
不明白的童鞋在评论区留言咯 ヾ(•ω•`)o
The above is the detailed content of Easy to understand! Detailed explanation of VUEX state warehouse management. For more information, please follow other related articles on the PHP Chinese website!
Hot AI Tools
Undresser.AI Undress
AI-powered app for creating realistic nude photos
AI Clothes Remover
Online AI tool for removing clothes from photos.
Undress AI Tool
Undress images for free
Clothoff.io
AI clothes remover
AI Hentai Generator
Generate AI Hentai for free.
Hot Article
Hot Tools
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
Hot Topics
1378
52
How to add functions to buttons for vue
Apr 08, 2025 am 08:51 AM
You can add a function to the Vue button by binding the button in the HTML template to a method. Define the method and write function logic in the Vue instance.
How to reference js file with vue.js
Apr 07, 2025 pm 11:27 PM
There are three ways to refer to JS files in Vue.js: directly specify the path using the <script> tag;; dynamic import using the mounted() lifecycle hook; and importing through the Vuex state management library.
How to use watch in vue
Apr 07, 2025 pm 11:36 PM
The watch option in Vue.js allows developers to listen for changes in specific data. When the data changes, watch triggers a callback function to perform update views or other tasks. Its configuration options include immediate, which specifies whether to execute a callback immediately, and deep, which specifies whether to recursively listen to changes to objects or arrays.
How to use bootstrap in vue
Apr 07, 2025 pm 11:33 PM
Using Bootstrap in Vue.js is divided into five steps: Install Bootstrap. Import Bootstrap in main.js. Use the Bootstrap component directly in the template. Optional: Custom style. Optional: Use plug-ins.
How to return to previous page by vue
Apr 07, 2025 pm 11:30 PM
Vue.js has four methods to return to the previous page: $router.go(-1)$router.back() uses <router-link to="/" component window.history.back(), and the method selection depends on the scene.
Vue realizes marquee/text scrolling effect
Apr 07, 2025 pm 10:51 PM
Implement marquee/text scrolling effects in Vue, using CSS animations or third-party libraries. This article introduces how to use CSS animation: create scroll text and wrap text with <div>. Define CSS animations and set overflow: hidden, width, and animation. Define keyframes, set transform: translateX() at the beginning and end of the animation. Adjust animation properties such as duration, scroll speed, and direction.
How to query the version of vue
Apr 07, 2025 pm 11:24 PM
You can query the Vue version by using Vue Devtools to view the Vue tab in the browser's console. Use npm to run the "npm list -g vue" command. Find the Vue item in the "dependencies" object of the package.json file. For Vue CLI projects, run the "vue --version" command. Check the version information in the <script> tag in the HTML file that refers to the Vue file.
How to use function intercept vue
Apr 08, 2025 am 06:51 AM
Function interception in Vue is a technique used to limit the number of times a function is called within a specified time period and prevent performance problems. The implementation method is: import the lodash library: import { debounce } from 'lodash'; Use the debounce function to create an intercept function: const debouncedFunction = debounce(() => { / Logical / }, 500); Call the intercept function, and the control function is called at most once in 500 milliseconds.


