当前位置:   article > 正文

Vuex的使用及原理_vuex的原理和使用方法

vuex的原理和使用方法

一、Vuex 是什么?

Vuex是专门为Vuejs应用程序设计的一款状态管理模式,类似于React中的Redux。它采用集中式存储管理应用的所有组件的状态。

  • 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • 个人理解:Vuex就是用来进行组件之间进行数据交换的第三方 “仓库”,组件可以把想要共享的数据存放在这里面,别的组件想要的之后直接调取即可。

Vuex原理理解 

个人理解它就是通过 全局混入 一个对象,在该对象的 beforeCreate 声明周期函数中,对每一个组件添加了一个属性 $store,值就是使用Vuex时所创建的Vuex实例。

1、 Vuex的构成 

  • state

state 是 Vuex 的数据中心,也就是说state是用来存储数据的。

  • Getters

getters 和 组件的 computed 类似,方便直接生成一些可以直接用的数据。当组装的数据要在多个页面使用时,就可以使用 getters 来做。

  • Mutations

mutations提交更改数据,使用store.commit方法更改state存储的状态。

  • Actions

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

 2、Vuex的使用方式

安装Vuex

方式一: npm 方式

npm install vuex --save

在应用中引入Vuex

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)   

在 Vue 组件中获得 Vuex 状态(State) 

 方式一: this.$store.state获取

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到

  1. const Counter = {
  2. template: `<div>{{ count }}</div>`,
  3. computed: {
  4. count () {
  5. return this.$store.state.count
  6. }
  7. }
  8. }

 方式二: mapState 辅助函数获取(推荐)

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

  1. import { mapState } from "vuex";
  2. export default {
  3. // ...
  4. computed: mapState({
  5. // 箭头函数可使代码更简练
  6. count: state => state.count,
  7. // 传字符串参数 'count' 等同于 `state => state.count`
  8. countAlias: 'count',
  9. // 为了能够使用 `this` 获取局部状态,必须使用常规函数
  10. countPlusLocalState (state) {
  11. return state.count + this.localCount
  12. }
  13. })
  14. }

 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

  1. computed: mapState([
  2. // 映射 this.count 为 store.state.count
  3. 'count'
  4. ])

 Getter的获取方式

有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:

  1. computed: {
  2. doneTodosCount () {
  3. return this.$store.state.todos.filter(todo => todo.done).length
  4. }
  5. }

 Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

方式一: 通过属性访问

    store.getters.doneTodos

 方式二: 通过方法访问

你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。

  1. getters: {
  2. // ...
  3. getTodoById: (state) => (id) => {
  4. return state.todos.find(todo => todo.id === id)
  5. }
  6. }
    store.getters.getTodoById(2)

注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。

方式三: mapGetters 辅助函数获取(推荐)

  1. import { mapGetters } from 'vuex'
  2. export default {
  3. // ...
  4. computed: {
  5. // 使用对象展开运算符将 getter 混入 computed 对象中
  6. ...mapGetters([
  7. 'doneTodosCount',
  8. 'anotherGetter',
  9. // ...
  10. ])
  11. }
  12. }

 如果你想将一个 getter 属性另取一个名字,使用对象形式:

  1. mapGetters({
  2. // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  3. doneCount: 'doneTodosCount'
  4. })

 Mutation使用方式

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

使用常量替代 Mutation 事件类型

  1. // mutation-types.js
  2. export const SOME_MUTATION = 'SOME_MUTATION'
  1. // store.js
  2. import Vuex from 'vuex'
  3. import { SOME_MUTATION } from './mutation-types'
  4. const store = new Vuex.Store({
  5. state: { ... },
  6. mutations: {
  7. // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
  8. [SOME_MUTATION] (state) {
  9. // mutate state
  10. }
  11. }
  12. })

在组件中提交 Mutation

你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。

  1. import { mapMutations } from 'vuex'
  2. export default {
  3. // ...
  4. methods: {
  5. ...mapMutations([
  6. 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
  7. // `mapMutations` 也支持载荷:
  8. 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
  9. ]),
  10. ...mapMutations({
  11. add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
  12. })
  13. }
  14. }

 Action使用方式

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。当我们在之后介绍到 Modules 时,你就知道 context 对象为什么不是 store 实例本身了。

  1. const store = new Vuex.Store({
  2. state: {
  3. count: 0
  4. },
  5. mutations: {
  6. increment (state) {
  7. state.count++
  8. }
  9. },
  10. actions: {
  11. increment (context) {
  12. context.commit('increment')
  13. }
  14. }
  15. })

 分发 Action

  1. // 以载荷形式分发
  2. store.dispatch('incrementAsync', {
  3. amount: 10
  4. })
  5. // 以对象形式分发
  6. store.dispatch({
  7. type: 'incrementAsync',
  8. amount: 10
  9. })

在组件中分发 Action

你在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store)

  1. import { mapActions } from 'vuex'
  2. export default {
  3. // ...
  4. methods: {
  5. ...mapActions([
  6. 'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
  7. // `mapActions` 也支持载荷:
  8. 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
  9. ]),
  10. ...mapActions({
  11. add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
  12. })
  13. }
  14. }

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号