Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式 + 库。
它采用集中式存储管理应用的所有组件的状态
简单理解就是:多个组件共享状态的时候使用
网址:vuex
使用
安装
npm install vuex@next --save
简单使用
src/store/index.js
import { createStore } from "vuex";
const store = createStore({
// 共享的状态
state: {
count:0
},
// 更新状态的
mutations: {
changeCount(state) {
state.count++;
}
},
});
export default store;
main.js
import { createApp } from "vue";
import App from './App.vue'
import store from "./store"; // 导入vuex,也就是store仓库的路径
createApp(App)
.use(store) // vuex
.mount("#app");
使用
- 通过
store.state来获取状态对象 - 通过
store.commit方法触发状态变更
console.log(store.state.count) // -> 0
store.commit('changeCount')
console.log(store.state.count) // -> 1
vue组件中
- 通过
store访问store实例。 - 现在我们可以从组件的方法提交一个变更:
import { useStore } from "vuex";
const store = useStore();
const changeHandle = () => {
store.commit('changeCount')
console.log(store.state.count)
}
注:
- 我们通过提交 mutation 的方式,而非直接改变
store.state.count,是因为这样可以追踪到状态的变化 - 记录每次状态改变,保存状态快照到调试工具
核心概念
state
- 在 state 中定义共享的状态
定义
import { createStore } from "vuex";
const store = createStore({
// 共享的状态
state: {
count:0,
count2:"abc"
},
});
export default store;
使用
import { useStore } from "vuex";
const store = useStore();
store.state.count
store.state.count2
mutations
- 更新 state 状态的
- 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
- 只支持同步更新
定义
import { createStore } from "vuex";
const store = createStore({
// 共享的状态
state: {
count:1,
},
// 更新状态
mutations:{
changeCount(state,value) {
state.count += value;
}
}
});
export default store;
使用
import { useStore } from "vuex";
const store = useStore();
const changeHandle = () => {
store.commit('changeCount',10) // -> 11
}
actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。(同步和异步)
例:
import { createStore } from "vuex";
const store = createStore({
// 共享的状态
state: {
list:[]
},
// 更新状态
mutations:{
changeList(state,value) {
// 旧数据 + 新数据
state.list = [...state.list,...value]
}
},
// 异步请求
actions: {
async getList(store) {
let res = await axios.get("地址");
store.commit("changeList", res.data.list); // 更新状态
},
},
// 类似于组件中的计算属性,
// 定义的时候像方法,使用的时候像变量
getters: {
getNowPlayingFilms(state) {
// 只要前三条数据,
// 用在详情页的猜你喜欢里面
return state.nowPlayingFilms.slice(0, 3);
},
},
});
getters
- 类似于组件中的计算属性,
- 定义的时候像方法,使用的时候像变量
定义
const store = createStore({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos (state) {
return state.todos.filter(todo => todo.done)
}
}
})
使用
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Module
- 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿
- 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
定义
const moduleA = {
state: () => ({
count:true,
list:[]
}),
mutations: {
changeCount(state, value) {
state.count = value;
},
changeList(state,value){
state.list = value
}
},
actions: {
async getList(store) {
let res = await axios.get("地址");
store.commit("changeList", res.data.list); // 更新状态
},
},
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
使用
- 修改状态state中的值,要走mutations
import { useStore } from "vuex";
const store = useStore();
store.commit("a/changeCount",false);
- 要重新请求接口,获取新数据
import { useStore } from "vuex";
const store = useStore();
store.dispatch("a/getList");
命名空间
- 设置
namespaced: true
vuex持久化插件
安装
npm install --save vuex-persistedstate
使用
import { createStore } from "vuex";
import createPersistedState from "vuex-persistedstate"; // vuex持久化插件,可以把一些状态存到本地存储中
import footerNavStore from "./module/FooterNavStore";
import nowPlayingFilmsStore from "./module/nowPlayingFilmsStore";
import cityStore from "./module/cityStore";
const store = createStore({
// 管理的模块
modules: {
footerNavStore,
nowPlayingFilmsStore,
cityStore,
},
// 把城市持久化,存储到本地存储中
plugins: [
createPersistedState({
reducer(state) {
return {
currentCity: state.cityStore.currentCity,
};
},
}),
],
});