vuex

官网:https://vuex.vuejs.org/zh-cn/

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。

Vue 的这些核心概念:

  • State
  • Getter
  • Mutation
  • Action
  • Module
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export const store = new Vuex.Store({
    // 存储(状态)数据
    state: {
        products: [
        {name:'纯种马',price:200},
        {name:'蒙古马',price:140},
        {name:'夸特马',price:20},
        {name:'阿拉伯马',price:10}
      ]
    },

    // 获得state数据作为参数,定义公共方法
    getters: {
        saleProducts: (state)=>{
            var saleProducts = state.products.map(product => {
                return {
                    name: "**" + product.name + "**",
                    price: product.price/2
                }
            });
            return saleProducts;
        }
    },
    
    // 触发事件改变数据
    // 非常类似于事件,每个mutations都有一个事件类型(type)和一个回调函数(handler)
    // 回调函数的第一个参数为state,第二个参数为payload
    mutations: {
        reducePrice: (state,payload) => {
            state.products.forEach(product =>{
                product.price -= payload;
            });
        }
    },

    // 类似mutations
    // 可以包含任意异步操作
    // 接受与store一样的context对象,这样就可以调用context.commit提交一个mutation
    actions: {
        reducePrice: (context,payload) => {
            setTimeout(function(){
                context.commit('reducePrice',payload);
            },2000);
        }
    }

一、引入

  1、安装

   npm install vuex --save 

  2、新建一个store文件夹,并在文件夹下新建store.js文件,文件中引入我们的vue和vuex。

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

Vue.use(Vuex);

  3、在main.js引入store并注册

   import {store} from './store/store.js' 

new Vue({
  store: store,
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

二、一个简单的Store

  每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。  

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

  由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。

  通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更。

<button @click="$store.commit('add')"></button>
<p>{{$store.state.count}}</p>

三、state访问状态对象

  1、通过computed的计算属性直接赋值

    computed属性可以在输出前,对data中的值进行改变。

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

    注意,这里要使用this,不然找不到$store。

  2、通过mapState的对象来赋值

    首先要用import引入mapState

import {mapState} from 'vuex';

    然后还在computed计算属性里写如下代码:

computed:mapState({
        count:state=>state.count
 })

  3、通过mapState的数组来赋值  

computed:mapState(['count'])

  使用方便简单,实际项目经常用

  4、mapState与局部计算属性混合使用,使用对象展开运算符  

 computed: {
    ...mapState(['count'])
  }

 

四、Mutations修改状态

  更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。

  Mutations必须是同步的。

  1、$store.commit()    

<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>

  2、提交载荷(Payload) --传值

   可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)

const mutations={
    add(state,payload){
        state.count+=payload;
    },
    reduce(state){
        state.count--;
    }
}
<p>
   <button @click="$store.commit('add',10)">+</button>
   <button @click="$store.commit('reduce')">-</button>
</p>

  3、模板获取Mutations方法 

<script>
import { mapState, mapMutations } from "vuex";

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations([
      'add',
      'reduce'
    ])
  }
};
</script>
<button @click="add(5)"></button>
<button @click="reduce(20)"></button>

  4、使用常量替代 Mutation 事件类型

    使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然:

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state) {
      // mutate state
    }
  }
})

 五、getters计算过滤操作

  getters字面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。可以认为是 store 的计算属性。

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

  在组件中使用它:

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

  

  mapGetters 辅助函数:

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

六、actions异步修改状态

  Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

  实践中,我们会经常用到 ES2015 的 参数解构 来简化代码:

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

  在组件中分发 Action

  在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用。

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

七、module模块组

  随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。

  1、声明模块组

const moduleA={
    state,mutations,getters,actions
}  
export default new Vuex.Store({
    modules:{a:moduleA}
})

  2、在模板中使用

    插值的方式引入

<h3>{{$store.state.a.count}}</h3>

  

    在计算属性中引入

computed:{
    count(){
        return this.$store.state.a.count;
    }
},
原文地址:https://www.cnblogs.com/lshilin/p/7709769.html