vue Vuex

发布于:2022-11-13 ⋅ 阅读:(517) ⋅ 点赞:(0)

一、Vuex 是什么?

Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。点击去官方文档

二:为什么要使用?

  • 多个视图依赖于同一状态
    传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

  • 来自不同视图的行为需要变更同一状态
    我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,把所有需要 共享状态 单独提取出来,使代码将会变得更结构化且易维护。

原理图如下:
在这里插入图片描述

三、开始

  1. 创建文件:src/store/index.js
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    
    //应用Vuex插件
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {},
      getters: {},
      mutations: {},
      actions: {},
      modules: {}
    })
    
  2. main.js 中创建vm时传入 store 配置项
    //引入store
    import store from './store'
    
    //创建vm
    new Vue({
    	el:'#app',
    	render: h => h(App),
    	store
    })
    

四、核心概念

State

状态对象是一个是纯粹 (plain) 的对象,保存具体的数据

const state = {
  // 购物车数量
  cartNum: 0,
  // ...
}

在组件中使用

<template>
  <div>
    <span>{{cartNum}}</span>
  </div>
</template>

<script>

export default {
  data() {
    return {}
  },
  computed: {
    cartNum() {
      return this.$store.state.cartNum
    },
  },
}
</script>

Getter

当有多个组件需要 state 中的数据经过加工后再使用时,可以使用getters加工。

export default new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
  	// 接受 state 作为其第一个参数:
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },

	// 也可以接受其他 getter 作为第二个参数,来调用其他 getter
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    }
  },
})

在组件中使用

<template>
  <div>
    <span>{{doneTodosCount}}</span>
  </div>
</template>

<script>

export default {
  data() {
    return {}
  },
  computed: {
    doneTodosCount() {
      return this.$store.getters.doneTodosCount
    },
  },
}
</script>

Action

处理业务逻辑的地方,以包含任意异步操作,不建议在这里直接修改 state 中的状态

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,且必须是同步函数,方法名一般规定为大写

五、 四个map方法的使用

使用前需要导入

import {mapState, mapGetters, mapActions, mapMutations} from 'vuex'

mapState

computed: {
  // 借助mapState生成计算属性:sum、school、subject(对象写法)
  ...mapState({sum:'sum',school:'school',subject:'subject'}),

  // 借助mapState生成计算属性:sum、school、subject(数组写法)
  ...mapState(['sum','school','subject']),
},

mapGetters

computed: {
  // 借助mapGetters生成计算属性:bigSum(对象写法)
  ...mapGetters({bigSum:'bigSum'}),

  // 借助mapGetters生成计算属性:bigSum(数组写法)
  ...mapGetters(['bigSum'])
},

mapActions

若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

methods:{
  // 靠mapActions生成:increment、decrement(对象形式)
  ...mapActions({increment:'increment',decrement:'decrement'})

  // 靠mapActions生成:increment、decrement(数组形式)
  ...mapActions(['increment','decrement'])
}

mapMutations

若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

methods:{
  // 靠mapMutations生成:increment、decrement(对象形式)
  ...mapActions({increment:'increment',decrement:'decrement'})

  // 靠mapMutations生成:increment、decrement(数组形式)
  ...mapActions(['increment','decrement'])
}

六、模块化 Module

模块化 + 命名空间,让代码更好维护,让多种数据分类更加明确。
每个模块化中必须 namespaced: true 开启命名空间,可以把每个模块拆分成单独的文件存放

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'

//应用Vuex插件
Vue.use(Vuex)

// 计数模块
const countAbout = {
  namespaced: true,
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {}
}
  
// 人员模块
const personAbout = {
  namespaced: true,
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {}
}

export default new Vuex.Store({
  modules: {
    cart,
    products,
  }
})
  1. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  2. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  3. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  4. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    
本文含有隐藏内容,请 开通VIP 后查看