一些关于 Vuex 的理解和基本用法 | 青训营笔记

151 阅读3分钟

一些关于 Vuex 的理解和基本用法

这是我参与第四届青训营笔记创作活动的第2天

在大项目中经常会遇到数据传值的问题,如果仅仅使用组件之间共享数据的方式进行数据传值,不仅大大增加了代码量,还不利于后期维护。而 Vuex 就很好的解决了这个问题,下面将简单介绍 Vuex,以及在项目中如何使用它。

1.Vuex 概述

1.1 组件之间共享数据的方式

父向子传值:v-bind 属性绑定
子向父传值:v-on 事件绑定
兄弟组件之间共享数据:EventBus

  • $on 接收数据的那个组件
  • $emit发送数据的那个组件

1.2 Vuex是什么

Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。

1.3 使用 Vuex统一管理状态的好处

  • ① 能够在vuex中集中管理共享的数据,易于开发和后期维护
  • ② 能够高效地实现组件之间的数据共享,提高开发效率
  • ③ 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步

1.4 什么样的数据适合存储到Vuex中

一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的 data中即可。

2.Vuex的核心概念

Vuex中的主要核心概念如下:

  • State
  • Mutation
  • Action
  • Getter

State

State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储。

    // 创建store数据源,提供唯一公共数据
    const store = new Vuex.Store({ 
        state:{ count: 0 }
    }) 

组件访问 State 中数据的第一种方式

    this.$store.state.全局数据名称 

组件访问 State 中数据的第二种方式

    // 1.从 vuex 中按需导入 mapstate 函数 
    import { mapstate } from 'vuex' 

通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:

    // 2.将全局数据,映射为当前组件的计算属性
    computed:{
        ...mapstate(['count']) 
    }

实际开发中,根据需求选择方式。
如果页面很多地方用到count,采用第二种方式会更好

Mutation

Mutation用于变更Store中的数据。
① 只能通过 mutation 变更 Store数据,不可以直接操作Store中的数据。
② 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。

//定义 Mutation
    const store = new Vuex.Store({ 
        state:{
            count:0 
        },
        mutations:{ 
            add(state) { 
                // 变更状态
                state.count++ 
            }
        }
    })

commit函数的作用,就是调用 mutations 内某个函数

    // 触发mutation
    methods:{ 
        handle1(){
            // 触发 mutations 的第一种方式 
            this.$store.commit('add') 
        }
    } 

不要直接在组件中绑定事件修改 vuex 里的共享数据,这样是不合法的,如果要修改对应的数据事件还要找到对应的组件

可以在触发 mutations 时传递参数:

    // 定义Mutation
    const store = new Vuex.Store({ 
        state:{
            count:0 
        },
        mutations:{
            addN(state,step){ 
                // 变更状态
                state.count += step 
            }
        }
    }) 
    
    // 触发mutation
    methods:{ 
        handle2(){
            // 在调用 commit 函数, 
            // 触发 mutations 时携带参数 
            this.$store.commit('addN', 3) 
        }
    }

this.$store.commit() 是触发mutations的第一种方式,触发mutations的第二种方式

    // 1.从 vuex 中按需导入 mapMutations 函数 
    import { mapMutations } from 'vuex' 

通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法:

    // 2.将指定的 mutations 函数,映射为当前组件的 methods 函数
    methods:{
        ...mapMutations(['add','addN']) 
    }

Action

Action用于处理异步任务。

注意:不要在 mutations 函数中,执行异步操作

如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。

    //定义 Action
    const store = new Vuex.Store({
        ...省略其他代码
        mutations:{ 
            add(state){ 
                state.count++ 
            }
        },
        actions:{
            addAsync(context){ 
                setTimeout(()=>{ con
                    text.commit('add')
                },1000)
            } 
        } 
    }) 

这里的 dispatch 函数,专门用来触发 action 内的函数

// 触发 Action
    methods:{ 
        handle(){
             //触发 actions的第一种方式
             this.$store.dispatch('addAsync') 
        }
    }    

触发 actions 异步任务时携带参数:

在 action 中,不能直接修改 state 中的数据。必须通过 context.commit() 触发某个 mutation 才行

    // 定义 Action
    const store = new Vuex.Store({ 
        // ...省略其他代码
        mutations:{
            addN(state, step){ 
                state.count+=step 
            }
        },
        actions:{
            addNAsync(context,step){ 
                setTimeout(()=>{
                    context.commit('addN', step) 
                }, 1000)
        } 
    }) 
    
    // 触发 Action
    methods:{ 
        handle(){
        // 在调用 dispatch 函数 
        // 触发 actions 时携带参数
        this.$store.dispatch ('addNAsync', 5) 
        }
    } 

context 可以理解为是 Vuex 这个实例对象,里面含有commit方法,可以访问到 mutations 里的方法

this.$store.dispatch() 是触发actions的第一种方式,触发actions的第二种方式

    // 1.从 vuex 中按需导入 mapActions 函数
    import { mapActions } from 'vuex'

通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法:

    // 2.将指定的 actions 函数,映射为当前组件的 methods 函数
    methods:{
        ...mapactions (['addAsync', 'addNasync']) 
    }

Getter

Getter 用于对Store中的数据进行加工处理形成新的数据。
① Getter可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性computed
② Store中数据发生变化,Getter的数据也会跟着变化。

    //定义 Getter
    const store=new Vuex.store({ 
        state:{
            count:0 
        },
        getters:{ 
            showNum: state => {
                return '当前最新的数量是【'+ state.count +'】' 
            }    
        } 
    }) 

使用 getters的第一种方式

    this.$store.getters.名称 

使用 getters的第二种方式

    import { mapGetters } from 'vuex' 
    computed:{
        ...mapGetters(['showNum']) 
    }