16 状态管理——Vuex

目录

16.1 安装Vuex

16.2 基本用法

16.2.1 State

16.2.2  Getter

16.2.3  Mutation

16.2.4  Action

16.2.5  Module

16.1 安装Vuex

        模块化开发的安装方式

# npm 安装
npm install vuex@next --save

# yarn安装
yarn add vuex@next --save

16.2 基本用法

        Vuex使用单一状态树,就是说,用一个对象包含了所有应用层级的状态,作为唯一的数据源而存在。每一个Vuex应用核心是store,store可以理解为保存应用程序状态的容器。store与普通的全局对象的区别有以下两点:

1. Vuex的状态存储是响应式的。当Vue组件从store中检索状态的时候,如果store中的状态发生变化,那么组件也会相应地得到高效更新。

2. 不能直接改变store中的状态。改变store中状态的唯一途径就是显示提交mutation。这可以确保每个状态更改都留下可跟踪的记录,从而能够启用一些工具来帮助我们更好地理解应用。

16.2.1 State

# store/index.js

import { createStore } from 'vuex'

const store = createStore({
    // 状态通过state()函数返回
    state () {
        return {
            count:0
        }
    },
})


export default store
# main.js

import { createApp } from 'vue'
import App from '/App.vue'
import store from './store'

createApp(App).use(store).mount('#app')

16.2.2  Getter

        getter相当于store的计算属性,它的作用是对state的数据做一些简单的事情,例如筛选、过滤操作。假设我们需要获取正在销售的图书,因此可以定义一个getter方法,对state中的books进行过滤。代码如下:

# store/index.js

import { createStore } from 'vuex'

const store = createStore({
    // 
    getters:{
        sellingBooks: state => state.books.filter(book => book.isSold === true)
    }
})


export default store

16.2.3  Mutation

         更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

# store/index.js

import { createStore } from 'vuex'

const store = createStore({
    strict: true,  // 严格模式
    // mutations选项中定义修改状态的方法
    // 这些方法接收state作为第1个参数
    mutations:{
        increment(state,n){
            state.count+=n
        }
    }
})


export default store

        更改状态的方法,需要通过mutation进行提交 

store.commit('increment', 10)

16.2.4  Action

        在定义mutation时,一条重要的原则是mutation必须是同步函数。换句话说,在mutation()处理器函数中,不能存在异步调用。如果需要执行异步操作,那么应该使用action。action类似于mutation,不同之处在于:

  • action提交的是mutation,而不是直接变更状态
  • action可以包含任意异步操作

一个简单的action如下:

# store/index.js

import { createStore } from 'vuex'

const store = createStore({
    strict: true,  // 严格模式
    // mutations选项中定义修改状态的方法
    // 这些方法接收state作为第1个参数
    mutations:{
        increment(state,n){
            state.count+=n
        }
    },
    actions:{
        increment(context){
            context.commit('increment')
        }
    }
})


export default store

         action处理函数接收一个与store实例具有相同方法和属性的context对象,因此可以利用该对象调用commit()方法提交mutation,或者通过context.state和context.getters访问state和getter。甚至可以用context.dispatch()调用其他的actiont。

        如果在action中需要多次调用increment,则可以考虑ES6中的解构语法解构代码。如下:

actions:{
    increment({ commit }) {
        commit('increment')
    }
}

 1.分发action

        action 通过store.dispatch()方法触发。代码如下:

store.dispatch('increment')

        action和mutation看似没什么区别,实际上它们之间最主要的是action中可以包含异步操作,例如:

actions:{
    incrementAsync({ commit }) {
        setTimeout(() =>{
            commit('increment')
        },1000)
    }
}

         action同样支持以载荷和对象的方式进行分发。代码如下所示:

// 载荷是一个简单的值
store.dispatch('incrementAsync',10)

// 载荷是一个对象
store.dispatch('incrementAsync',{
    amount:10
})

// 直接传递一个对象进行分发
store.dispatch({
    type:'incrementAsync',
    amount:10
})

16.2.5  Module

        Vuex使用单一状态树,应用程序的所有状态都包含在一个大的对象中,当应用变的复杂时,store对象就会变的非常臃肿。为了解决这个问题,Vuex允许将store划分为多个模块,每个模块可以包含自己的state、mutations、actions、getters及嵌套的子模块。例如:

const moduleA = {
    state: () => ({}),
    getters:{},
    mutations:{},
    actions:{}
}


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


const moduleC = {
    state: () => ({}),
    getters:{},
    mutations:{},
    actions:{}
}


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

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

       在一个大型项目中,如果store模块划分较多,Vuex建议项目结构按照以下形式组织:

| —— store                    
    | —————— index.js         #组装模块并导出store的地方
    | —————— actions.js       #根级别的actions
    | —————— mutations.js     #根级别的mutations
    | —————— modules.js       #根级别的modules
        | —————— car.js       #购物车模块
        | —————— products.js  #产品模块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值