vuex

4/23/2024 vuex

参考资料:

# 什么是Vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态。

# 解决了什么问题

  • 多个组件依赖于同一状态时,对于多层嵌套的组件的传参将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
  • 来自不同组件的行为需要变更同一状态。以往采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

# Vuex的5个核心属性是什么?

  • state: 存储状态。
  • getters: 可以理解为 state的计算属性,从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数。
  • mutations: 改变状态的方法,是改变状态的唯一途径,可以理解为 methods,在其中可以改变state
  • actions: mutations的升级版,他调用mutations,而且支持异步
  • modules: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
const moduleA = {
  state: () => ({
    count: 0,
  }),
  getters: {
    doubleCount(){
      return count * 2
    },
  },
  mutations: {
    increment (state, val){
      state.count += val
    },
  },
  actions: {
    requestAndIncrement(context){
      setTimeout(()=>{
        context.commit('increment', 5)
      }, 1000)
    }
  },
  
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = createStore({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

// 使用
export default {
  computed: {
    count () {
      return this.$store.state.count
    },
    // 批量简介引入,使用mapState,同理也有 mapMutations和mapActions(定义在methods中)
    ...mapState(['count'])
  },
  methods: {
    increment(val){
      this.$store.commit('increment', val)
      console.log(this.$store.state.count) // 等价于 console.log(this.count)
    },
    actionFunc(){
      this.$store.dispatch('requestAndIncrement') // 通过 dispatch 调用 action 的方法
    }
  }
}

# 在组件中批量使用Vuex的getter属性

使用mapGetters辅助函数

import {mapGetters} from 'vuex'
export default{
  computed:{
    ...mapGetters(['total','discountTotal']),
    // 也可以支持创建别名
    ...mapGetters({
      totalAlias:'total',
      discountTotalAlias:'discountTotal',
    })
  }
}

# 在模块中,getter和mutation接收的第一个参数state,是全局的还是模块的?如何访问全局的state和getter?

第一个参数state是模块的state,也就是局部的state。

  • 在getter中可以通过第三个参数rootState访问到全局的state,可以通过第四个参数rootGetters访问到全局的getter。
  • 在mutation中不可以访问全局的satat和getter,只能访问到局部的state。
  • 在action中第一个参数context中的context.rootState访问到全局的state,context.rootGetters访问到全局的getter。

# 在v-model上怎么用Vuex中state的值?

需要通过computed计算属性来转换。

<input v-model="message">
// ...
computed: {
  message: {
    get () {
      return this.$store.state.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

# 刷新页面vuex数据丢失的原因和数据持久化的方法

刷新页面会导致 Vue 应用重新加载,并且重新初始化 Vue 实例和 Vuex 状态。

通过 localStorage 实现数据持久化

state: {
  count: localStorage.getItem('count') || 0
},
mutations: {
  increment(state){
    state.count ++
    localStorage.setItem('count', state.count)
  }
}

# vuex和localStorage的区别

vuex localStorage
存储位置 Vuex存储在应用的内存中 localStorage将数据以文件形式存储在浏览器的本地存储空间中
数据类型 任意类型的数据 仅能存储字符串类型的数据,若存储对象,需要通过JSON的stringify和parse方法进行处理
应用场景 用于Vue.js应用程序中,用于组件间的状态管理,确保状态以可预测的方式变化 用于不同页面间的数据传递
数据共享方式 Vuex中的数据是共享的,不同组件间可以访问和修改同一数据状态 独立的,每个页面或窗口有自己的数据状态
数据容量限制 Vuex受内存大小限制 localStorage的数据存储量通常约为5MB
永久性 在页面刷新时存储的值会丢失 localStorage存储的数据在页面刷新或关闭浏览器后不会丢失