Vue框架学习 ----5.vuex

vuex的东西比较碎,还是要慢慢理解。

一、vuex介绍

对 vue 应用中多个组件的共享状态进行集中式的管理(读/写)。

1.1 组成部分

  • state,核心,保存应用程序状态的容器,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

    在这里插入图片描述


    作用:解决多个视图依赖于同一状态, 来自不同视图的行为需要变更同一状态

二、核心概念

2.1 state

存储状态(变量),包含了全部的应用层级状态

const store = new Vuex.Store({
  state:{
    //存放的键值对就是所要管理的状态
    count:0
  }
})


通过计算属性获取store中状态

computed:{
    count(){
        return this.$store.state.count;
    }
}
mapState函数

用于生成计算属性

使用

// 引入
import { mapState } from 'vuex'
computed:mapState({
    count: 'count',
    msg: 'message'
})

注:如果计算属性要使用组件中的数据属性,那么就需要使用普通函数的方式

写法二:
计算属性的名字与store中状态属性的名字相同,则可以进一步简化,写法如下:

computed:mapState([
        'count',
        'message'
])

写法三:
混入本地计算属性

computed:{
    localComputed (){return '本地计算属性' } ,
    ...mapState([
       'count', 'message'
     ])
}

2.2 mutations

是操作state数据的方法的集合,更改 Vuex 的 store 中的状态的唯一方法是提交mutation。mutation非常类似于事件。

const store = new Vuex.Store({
  state:{
    //存放的键值对就是所要管理的状态
    count:0
  },
  // 一个方法就是一个 mutation
  // mutation 只能包含更新 state 的同步代码, 也不会有逻辑
  mutations:{
    // state:当前VueX对象中的state
    // data:该方法在被调用时传递的参数
    increment(state,data){
        state.count+=data
    }
  }
})

提交mutation

this.$store.commit('increment',1)

使用包含type属性的对象提交

 this.$store.commit(
 {
    type:'increment',
    amount:10
 })
mapMutations函数

可以将组件中的方法映射为store.commit调用

写法1:

methods:mapMutations(
     ['increment','decrement']
),

写法2:组件中有自己的方法,可通过es6展开运算符,提取mapMutations函数返回的对象属性,复制到methods选项中

methods:{
    ...mapMutations(
        ['increment','decrement']
    ),
    test(){}
}

2.3 getter

可理解为store的计算属性,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

定义:

const store = new Vuex.Store({
  ....
  getters:{
    userName:state =>state.firstName+state.lastName
  }
})

直接使用

<h1>姓名:{{this.$store.getters.userName}}</h1>
mapGetters

获取getters计算属性

computed:{
    ...mapGetters(['userName'])
}

2.4 action

Action 类似于 mutation,不同在于:

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

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,
调用 context.commit 提交一个 mutation
或者通过 context.state 和 context.getters 来获取 state 和 getters

 actions:{
    increment(context){
      context.commit('increment',1)
    }
  }

触发

<button @click="$store.dispatch('increment',3)">+3</button>

与mutation最主要的区别就是action中可以包含异步操作

actions:{
  increment (context,data) {
    setTimeout(() => {
      context.commit('increment',data)
    }, 1000)
  }
}
mapActions

将组件的方法映射为store.dispatch调用

methods:{
        ...mapActions(['increment'])
    }

2.5 数据流向图

官方图
在这里插入图片描述

补充图
在这里插入图片描述

2.6 module

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

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

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

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

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

对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState

    actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
            console.log("局部aciton被调用")
            console.log("state.count:"+state.count)
            console.log("rootState.count:"+rootState.count)
             commit('increment')
        }
    }

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来

getters: {
        sumWithRootCount (state, getters, rootState) {
            return state.count + rootState.count
        }
    },

注:模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

命名空间

通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

export const moduleA = {
    namespaced: true,
    ....
}

组件调用

methods:{
        ...mapActions('a',['incrementIfOddOnRootSum']),
       /* add(){
            this.$store.dispatch('a/incrementIfOddOnRootSum')
        }*/
    }

内部调用

 actions: {
        someOtherAction(context){
            console.log("局部acition被调用")
        },
        incrementIfOddOnRootSum (context) {
            console.log("局部getters:"+context.getters.someGetter)// -> 'moduleA/someGetter'
            console.log("全局getters:"+context.rootGetters.someGetter)// -> 'someGetter'
            context.dispatch('someOtherAction') // -> 'moduleA/someOtherAction'
            context.dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
            context.commit('increment') // -> 'moduleA/someMutation'
            context.commit('increment', null, { root: true }) // -> 'someMutation'
        }
    }
computed:{
        ....
        sumCount (){
            return this.$store.getters['moduleA/someGetter']
        }
    },
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值