Vuex从入门到实战(一)

魏晓巍

发布于 2020.04.17 16:04 阅读 2749 评论 0

目标:

  1. 能够说出vuex使用的基本步骤
  2. 能够说出vuex的核心概念
  3. 能够基于vuex实现业务

1.vuex概述

1.1vuex是什么?

vuex是实现组件全局状态(数据)管理的一种机指,可以方便的实现组件之间得数据共享。

不使用vuex的数据传递方式和使用vuex的数据传递方式对比图:

 

 

可见,频繁的大范围的数据共享,使用vuex是非常方便并且简洁的。

1.2使用vuex统一管理的状态的好处

  1. 能够再vuex中几种管理共享数据,易于开发和后期维护
  2. 能够高效地实现组件之间的数据共享,提高开发效率
  3. 存储在vuex中的数据都是响应式的,能够实时保持数据于页面同步

1.3什么样的数据适合存储到vuex中

一般情况下,之哟组件之间共享的数据才有必要存储到vuex中;对于组件中私有的数据,依然存储到组件本身的data中。

2.vuex的基本使用

1.安装vuex依赖包

npm install vuex --save

 

2.导入vuex包

import Vuex from 'vuex'
Vue.user(Vuex)

 

3.创建store对象

const store = new Vuex.Store({
    // state 中存放的就是全局共享数据
    state: {count: 0}
})

 

4.将store对象挂载到vue实例中

new Vue({
    el: 'app',
    render: h => h(app),
    router,
    // 将创建的共享数据对象,挂载到Vue实例中
    // 所有的组件,就可以直接从store中获取全局的数据了
    store
})

 

N.计数器案例

N.1建立一个vue-cli项目,将vuex配置选中。

N.2将项目初始化,删除项目中自带的组件以及App.vue中的内容

N.3在components路径下创建两个组件addition.vue和substraction.vue

addition.vue:

<template>
  <div>
    <h3>当前最新的count值为</h3>
    <button>+1</button>
  </div>
</template>

<script>
export default {
  components: {},
  data () {
    return {}
  }
}
</script>

 

substraction.vue:

<template>
  <div>
    <h3>当前最新的count值为</h3>
    <button>-1</button>
  </div>
</template>

<script>
export default {
  components: {},
  data () {
    return {}
  }
}
</script>

 

N.4在App.vue中引入并且使用这两个组件

<template>
  <div id="app">
    <addition></addition>
    <Subtraction></Subtraction>
  </div>
</template>

<script>
import Addition from '@/components/addition.vue'
import Subtraction from '@/components/subtraction.vue'

export default {
  name: 'App',
  components: {
    Addition,
    Subtraction
  },
  data () {
    return {}
  }
}
</script>

 

3.vuex的核心概念

3.1vuex中的主要概念如下:

  • State
  • Mutation
  • Action
  • Getter

3.2State

State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储。

export default new Vuex.Store({
  state: {
    count: 0
  }
})

 

组件中访问State中数据的第一种方式:

this.$store.state.全局数据名称

 

组件中访问State中数据的第二种方式:

// 1.从vuex中按需导入mapState函数
import {mapState} from 'vuex'

 

通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:

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

 

虽然我们可以直接获取到store中存储的数据,并且这些数据都是双向绑定的,但是我们如果直接操作这些数据,是不规范的,我们要使用Mutation对Store中的数据进行变更。

3.3Mutation

Mutation用于变更Store中的数据。

  1. 只能通过Mutation变更Store中的数据,不可以直接操作Store中的数据。
  2. 通过这种方式虽然操作起来稍微繁琐一些,但是可以几种监控所有数据变化。
  3. 只有Mutation中的函数才有权利改变State中的数据。

定义Mutation:

export default new Vuex.Store({
  mutations: {
    add (state) {
      // 变更状态
      state.count++
    }
  }
})

 

3.3.1调用Mutation的第一种方法:

methods: {
    add () {
      // this.$store.commit.('方法名称')
      this.$store.commit('add')
    }
  }

 

在触发Mutation时传递参数,定义一个新的方法,可以接收增加的值:

  mutations: {
    addN (state, step) {
      // 变更状态
      state.count += step
    }
  },

 

触发带参数的Mutation:

    addN () {
      // this.$store.commit.('方法名称',参数值)
      this.$store.commit('addN', 3)
    }

 

PS:commit的作用就是调用某个Mutation。

3.3.2调用Mutation的第二种方法:

// 从vuex中按需导入mapMutations函数
import { mapMutations } from 'vuex'

 

通过导入的mapMutations 函数,映射为当前组件的methods方法:

  methods: {
    // 获取到Mutation中的方法
    ...mapMutations(['sub', 'subN']),
    // 无参调用
    sub_com () {
      this.sub()
    },
    // 带参调用
    subN_com () {
      this.subN(this.num)
    }
  }

 

PS:在Mutation中不能编写异步的代码。

3.4Action

Action用于处理异步任务。

如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Muation的方式简介更改数据。

使用dispatch专门调用Action中的方法!

如果我们想让计数方法延迟实现,就必须在Action中调用Mutation中的方法。

  mutations: {
    addN (state, step) {
      // 变更状态
      state.count += step
    }
  },
  actions: {
    // 这里的context相当于我们生命的Vuex.Store实例对象
    addAsync (context) {
      setTimeout(() => {
        // 在action中不能直接修改state中的数据
        // 必须通过 context.commit() 触发某个mutation才行
        context.commit('addN')
      }, 1000)
    }
  },

 

触发Action的第一种方式:

不带参:

    // 触发Action
    addN_act () {
      // 触发Action的第一种方式
      this.$store.dispatch('addAsync')
    }

 

带参:

Action中的方法:

    add_N_Async (context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    }

 

调用Action:

    add_N_act () {
      this.$store.dispatch('add_N_Async', parseInt(this.num))
    }

 

触发Action的第二种方式:

声明Action方法:

  subAsync (context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    sub_N_Async (context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }

 

调用Action方法:

导入mapActions :

// 从vuex中按需导入 mapActions 函数
import { mapActions } from 'vuex'

 

在methods中调用 mapActions 方法:

  ...mapActions(['subAsync', 'sub_N_Async']),
    sub_com_act () {
      this.subAsync()
    },
    // 带参调用
    subN_com_act () {
      this.sub_N_Async(this.num)
    }

 

3.5Getter

Getter用于对Store中的数据进行加工处理性成新的数据。

  1. Getter可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性(不过我觉得更像是filiters)。
  2. Store中数据发生变化,Getter的数据也会跟着变化。

定义Getter:

  getters: {
    showNum: state => {
      return `当前最新的数量是${state.count}`
    }
  },

 

使用Getters的第一种方法:

this.$store.getters.名称

 

使用Getters的第二种方法:

//引入mapGetters
import { mapGetters } from 'vuex'

//在computed中获取getters中的方法
  computed: {
    ...mapGetters(['showNum'])
  },