Vuex是什么

Vuex 是专门为 Vue.js 设计的状态管理库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

简单地说就是采用全局单例模式,将组件的共享状态抽离出来管理,使组件树中的每一个位置都可以获取共享的状态(变量)或者触发行为。

或者更直白的说就是响应式的全局变量

Vuex核心概念

State共享状态(即变量)
Getter基于state的派生状态,可理解为组件中的计算属性
Mutation更改vuex的store中状态的唯一方法,通过提交mutation修改状态,同步操作(规则上是不允许异步操作的,虽然异步也可以执行,但是对devtool调试的状态跟踪或多个状态更改操作相互依赖是很不好的,所以不要觉得只要不报错我就可以这么用,还是尽量按照规则来比较好)
Action类似mutation,不同之处,1.通过提交mutation修改状态 2.支持异步操作
Module模块,在大型项目中为了方便状态的管理和协作开发将store拆分为多个子模块(modules),每个子模块拥有完整的state、mutation、action、getter

Vuex安装

Vue2版本对应Vuex3的版本,否则会报错。

npm install vuex@3.0.1 --save

Vuex使用

1、新建store.js ,引入vue和vuex

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 登录验证
export default new Vuex.Store({

})

2、在根实例中注册store

import store from './vuex/store'
new Vue({
  store
)}

3、state状态

state: {
    menu: [],
    token: '',
    admin: '',
  },

调用

this.$store.state.x来访问vuex中定义的变量

4、mutation 更改store中状态的唯一方法

因为vuex中规定只能通过提交mutation的方式去更改store中的状态,包括action中的操作,也是通过提交mutation去修改。

另外一点就是vuex中规定mutation中不能包含异步操作。

mutations: {
    SET_MENU: (state, menu) => { state.menu = menu },
    SET_TOKEN: (state, token) => { state.token = token },
    SET_ADMIN: (state, admin) => { state.admin = admin }
  },

调用

this.$store.commit('SET_MENU', '')

5、action异步更改状态

上面在mutation的介绍中我们提到了,mutation中规则上是不允许异步操作的,那如果我们需要异步的进行更改状态怎么办?于是vuex为我们提供了action。

actions: {
    getSubject(context) {
      return axios({
        url: '/subject/getAll',
        method: 'get'
      }).then(res => {
        console.log('res', res.data)
        context.commit('SET_SUBJECT', res.data)
      })
    }
  }

action中不能直接更改状态,它是通过提交mutation来实现操作

它的参数是一个与 store 实例具有相同方法和属性的 context 对象,所以可以通过context.state来获取store中的状态,可以通过context.commit来提交更改等

action的调用使用 this.$store.dispatch

useAction() {
      this.$store.dispatch('getSubject', {
        name: this.name
      })
    }

action事件的定义分为有参和无参两种

action事件的触发同样可以使用载荷和对象两种方式

6、getter--store中state的派生状态

getter,我们可以理解为是对store中state的一些派生状态,也可以理解为一种计算属性,因为它像计算属性一样,返回值会根据它的依赖被缓存起来,且依赖对象发生改变的时候它才会被重新计算。

getter的使用对我来讲就是将对store中某个属性相同的处理操作抽出出来,做了一个公共的处理

getters: {
    GET_MENU: (state) => { return state.menu },
    GET_TOKEN: (state) => { return state.token },
    GET_ADMIN: (state) => { return state.admin }
  }

Vuex完整使用

import Vue from 'vue'
import Vuex from 'vuex'
import persistedstate from 'vuex-persistedstate' // vuex持久化到sessionStorage
Vue.use(Vuex)
export default new Vuex.Store({
  plugins: [persistedstate({
    storage: window.sessionStorage,
    reducer(val) {
      return {
        menu: val.menu,
        token: val.token,
        admin: val.admin
      }
    }
  })],
  state: {
    menu: [],
    token: '',
    admin: '',
  },
  mutations: {
    SET_MENU: (state, menu) => { state.menu = menu },
    SET_TOKEN: (state, token) => { state.token = token },
    SET_ADMIN: (state, admin) => { state.admin = admin }
  },
  getters: {
    GET_MENU: (state) => { return state.menu },
    GET_WHITE: (state) => { return state.white },
    GET_TOKEN: (state) => { return state.token },
    GET_ADMIN: (state) => { return state.admin }
  }
})

Vuex模块化

store => index.js

import HomeModule from './module/HomeModule'
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
export default new Vuex.Store({        // 持久化到localStorage
  plugins: [createPersistedState()], // 持久化 cnpm install --save vuex-persistedstate
  state: {},
  mutations: {},
  // 做异步  好处就是search和cinema都能用结果 不用一次一次请求了
  actions: {},
  // 各个模块
  modules: {
    HomeModule
  }
})

store => module => HomeModule.js

import axios from '@/http/config/axios.js'
const module = {
  namespaced: true, // 一定要有
  state: {
    isShow: '',
    indexHome: '',

  },
  mutations: {
    // 悬停触发index存值
    SET_SHOW: (state, isShow) => { state.isShow = isShow },
    SET_INDEXHOME: (state, args) => { state.indexHome = args },

  },
  getters: {
    GET_SHOW: (state) => { return state.isShow },
    GET_INDEXHOME: (state) => { return state.indexHome },

  },
  actions: {
    getSubject(context) {
      return axios({
        url: '/subject/getAll',
        method: 'get'
      }).then(res => {
        context.commit('SET_SUBJECT', res.data)
      })
    },
  }
}
export default module

模块化使用Vuex会借助辅助函数

<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
export default {
  name: 'TopNav',
  data() {
    return {}
  },
  computed: {
    ...mapGetters('HomeModule', ['GET_SHOW', 'GET_SUBJECT', 'GET_CLICKINDEX'])
  },
  methods: {
    ...mapMutations('HomeModule', ['SET_SHOW', 'SET_CLICKINDEX']),
    ...mapActions('HomeModule', ['getSubject'])
  },
}
</script>

...mapGetters要放在computed中 直接通过this.GET_SHOW调用

...mapMutations...mapActions要放在methods中 直接通过this.SET_SHOW调用

Vuex刷新页面丢失数据

细心的小伙伴在store.js中已经发现了引用插件

我们可以这样处理,在页面刷新或离开之前将store中的数据保存到sessionStorage 或 localStorage中,在页面重新加载后再将数据取出。

npm install --save vuex-persistedstate

在浏览器中应用程序本地存储或会话存储中可以看到vuex所存储的对象

最后修改:2022 年 02 月 27 日 12 : 49 AM
赏杯咖啡喝 谢谢您~