Vuex简单学习

1.Vuex是什么

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

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

2.核心概念(参考https://vuex.vuejs.org/zh/guide/modules.html)

  • state

Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

单状态树和模块化并不冲突——在后面的章节里我们会讨论如何将状态和状态变更事件分布到各个子模块中。

简单来说就是暂时存储数据的地方

const state = {
    xxx: initValue
}
  • actions

1) 包含多个事件回调函数的对象
2) 通过执行: commit()来触发 mutation 的调用, 间接更新 state
3) 谁来触发: 组件中: $store.dispatch('action 名称', data1) // 'zzz'
4) 可以包含异步代码(定时器, ajax)
 

const actions = {
    zzz ({commit, state}, data1) {
        commit('yyy', {data1})
    }
}
  • mutations

1) 包含多个直接更新 state 的方法(回调函数)的对象
2) 谁来触发: action 中的 commit('mutation 名称')
3) 只能包含同步的代码, 不能写异步代码

const mutations = {
    yyy (state, {data1}) {
        // 更新 state 的某个属性
    }
}

 

  • getters

1) 包含多个计算属性(get)的对象
2) 谁来读取: 组件中: $store.getters.xxx
 

const getters = {
    mmm (state) {
        return ...
    }
}
  • modules

1) 包含多个 module
2) 一个 module 是一个 store 的配置对象
3) 与一个组件(包含有共享数据)对应

官方结构图

个人结构图

 

 


计算小例子:

+/-:点击次数+/-1

increment if odd:如果是奇数+1

increment async:异步+1

Computer.Vue

<template>
  <div>
    <p>click {{$store.state.count}} times, count is {{$store.getters.evenOrOdd}}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">increment if odd</button>
    <button @click="incrementAsync">increment async</button>
  </div>
</template>

<script>

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

  export default {
    /*computed: {
      count () {
        return this.$store.state.count
      },
      evenOrOdd () {
        return this.$store.getters.evenOrOdd
      }
    },*/
    computed:{
      ...mapState(['count']),  //mapState()返回值  {count(){return this.$store.state.['count']}}
        ...mapGetters(['evenOrOdd'])

      /*
          如果函数名跟store对象中名称不一样
          ...mapXXX({store中函数名:'函数名'})
       */
    },
   methods:{
     ...mapActions(['increment','decrement','incrementIfOdd','incrementAsync'])
   }
  }
</script>

<style scoped>

</style>

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  count:0
}

const mutations = {
  INCREMENT(state) {
    state.count++
  },
  DECREMENT (state) { // ctrl + shift + x
    state.count--
  }
}
const actions = {
    increment({commit}){
      commit('INCREMENT')
    },
  decrement({commit}){
    commit('DECREMENT')
  }, incrementIfOdd({commit,state}){
    if(state.count%2===1) {
      // 提交一个mutation请求
      commit('INCREMENT')
    }
  },
  incrementAsync({commit}){
    setTimeout(() => {
      // 提交一个mutation请求
      commit('INCREMENT')
    }, 1000)
  }
}
const getters = {
  evenOrOdd(state){
    return state.count%2===0?"偶数":"奇数"
  }
}

//向外暴露store对象
export  default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

App.Vue

<template>
  <Counter/>
</template>

<script>
  import Counter from './components/Counter'
  export default {
   components:{
     Counter
   }
  }
</script>

<style>

</style>

main.js

/*
入口JS
 */
import Vue from 'vue'
import App from './App.vue'
import store from './store'

import './base.css'

// 创建vm
/* eslint-disable no-new */
/*new Vue({
  el: '#app',
  components: {App}, // 映射组件标签
  template: '<App/>', // 指定需要渲染到页面的模板
  store   //1.所有组件都有一个属性: $store
})*/

new Vue({
  el: '#app',
 render:h=>h(App),
  store
})

/*new Vue({
  el: '#app',
 render:function (createElement) {
    return createElement(App)
 },
  store
})*/

结果:

posted @ 2019-08-04 23:12  麦田的老哥  阅读(8)  评论(0)    收藏  举报