Vuex 状态管理库

110 阅读3分钟

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,
        };
      },
    }),
  ],
});