Vuex

下载

  •  npm install vuex@next --save 

思想

  • vuex 是一个数据管理的仓库
  • vuex 中有5个核心的配置选项   state 、 getters 、 mutations 、 actions 、 modules 
  •  state 选项用于存放数据
  •  getters 选项用于存放一些对 state 数据加工的数据,并且具有缓存功能
  •  mutations 选项中存放用于操作  state 数据的函数,所有操作  state 中的数据的函数都应该写在这里, mutations 中的函数应该是同步的
  •  actions 选项中可以有异步函数, actions 中配置的函数主要用于触发  mutations 中的函数,从而借用  mutations 中的函数修改  state 中的数据
  •  modules 选项的主要功能是将一个大的 vuex 拆分为多个小的 vuex

使用思路

  • 在组件中使用  this.$store.state 可以拿到 vuex 中  state 选项保存的数据
  • 在组件中使用  this.$store.getters 可以拿到 vuex 中  getters 选项中保存的数据
  • 在组件中使用  this.$store.commit('字符串函数名') 可以触发 mutations 选项中的函数
  • 在组件中使用  this.$store.dispatch('字符串函数名') 可以触发  actions 选项中的函数

配置

  • src/store/index.js
import {createStore} from 'vuex'

// 创建一个 store 实例
const store = createStore({
  state: { // 存放数据地方
    num: 1
  },
  mutations: { // 存放修改数据的地方
    INCREMENT(state, payload) {
      state.num += payload
    }
  },
  actions: { // 存放触发 mutations 的地方
    incrementWait(context, payload) {
      setTimeout(() => {
        context.commit('INCREMENT', payload)
      }, 1000)
    }
  },
  getters: { // 基于 state 数据进行加工的地方
    bigSum(state) {
      return state.num * 10
    }
  }
})

// 暴露
export default store

actions 选项中定义的函数,第一个参数是一个上下文对象  context ,可以通过上下文对象里面的  commit 函数调用  mutations 里面的函数,在上下文对象中也可以拿到  state 但不要直接修改里面的值而是要借助  mutations 里面的函数修改  state 的值

actions 选项中定义的函数,第二个参数是 组件使用  dispatch 触发时传递过来的

  • src/main
import { createApp } from 'vue'
import App from './App.vue'
import store from "./store"; // 引入

const app = createApp(App)
app
  .use(store) // 使用该插件

app.mount('#app')
  • 现在所有的组件都可以通过  this.$store 使用 vuex

基本使用

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{this.$store.state.num}}</div>
  <div>vuex中的getters中加工了的数据 {{this.$store.getters.bigSum}}</div>
  <div>
    <button @click="increment">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
export default {
  methods: {
    increment() {
      // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1
      this.$store.commit('INCREMENT', 1)
    },
    incrementWait() {
      // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10
     this.$store.dispatch('incrementWait', 10)
    }
  }
}
</script>
  • 使用  this.$store.state 可以拿到 vuex 中  state 中的数据
  • 使用  this.$store.getters 可以拿到 vuex 中  getters 加工的数据
  • 使用  this.$store.dispatch 可以触发 vuex 中  actions 里面的函数,并且在调用  dispatch 函数时可以传递1个参数
  • 使用  this.$store.commit  可以触发 vuex 中  mutations 里面的函数,并且在调用  commit 函数时可以传递 1 个参数

 优化模板中vuex的使用

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{num}}</div>
  <div>vuex中的getters中加工了的数据 {{bigSum}}</div>
  <div>
    <button @click="increment">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
export default {
  computed: {
    num() {
      return this.$store.state.num
    },
    bigSum() {
      return this.$store.getters.bigSum
    }
  },
  methods: {
    increment() {
      // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1
      this.$store.commit('INCREMENT', 1)
    },
    incrementWait() {
      // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10
     this.$store.dispatch('incrementWait', 10)
    }
  }
}
</script>
  • 借助计算属性,优化 vuex 的  state  和  getters  在模板中的使用 

mapState 和 mapGetters 再次优化Vuex的使用

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{num}}</div>
  <div>vuex中的getters中加工了的数据 {{bigSum}}</div>
  <div>
    <button @click="increment">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
import {mapState, mapGetters, } from 'vuex'
export default {
  computed: {
    ...mapState({num: 'num'}),
    ...mapGetters({bigSum: 'bigSum'})
  },
  methods: {
    increment() {
      // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1
      this.$store.commit('INCREMENT', 1)
    },
    incrementWait() {
      // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10
     this.$store.dispatch('incrementWait', 10)
    }
  },
}
</script>
  •  mapState 函数接收一个对象作为参数,对象中的 key 将作为一个  computed 计算属性,对象的 value 将映射到 vuex 中对应的 state。 mapState 函数的返回值是一个对象,需要在计算属性 computed 中解构出来
  •  mapGetters 函数接收一个对象作为参数,对象中的 key 将作为一个  computed 计算属性,对象的 value 将映射到 vuex 中对应的 getters 。 mapGetters 函数的返回值是一个对象,需要在计算属性 computed 中解构出来

mapState 和 mapGetters 的第二种写法

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{num}}</div>
  <div>vuex中的getters中加工了的数据 {{bigSum}}</div>
  <div>
    <button @click="increment">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
import {mapState, mapGetters, } from 'vuex'
export default {
  computed: {
    ...mapState(['num']),
    ...mapGetters(['bigSum'])
  },
  methods: {
    increment() {
      // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1
      this.$store.commit('INCREMENT', 1)
    },
    incrementWait() {
      // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10
     this.$store.dispatch('incrementWait', 10)
    }
  },
}
</script>
  • 调用  mapState 函数可以接收一个数组,数组中的每一个字符串属性与 Vuex 中对应的 state 保持映射关系
  • 调用  mapGetters 函数可以接收一个数组,数组中的每一个字符串属性与 Vuex 中对应的 getters 保持映射关系

mapMutations 和 mapActions优化Vuex的使用

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{num}}</div>
  <div>vuex中的getters中加工了的数据 {{bigSum}}</div>
  <div>
    <button @click="increment(1)">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait(10)">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex'
export default {
  computed: {
    ...mapState(['num']),
    ...mapGetters(['bigSum'])
  },
  methods: {
    ...mapMutations({increment: 'INCREMENT'}),
    ...mapActions({incrementWait: 'incrementWait'})
  },
}
</script>
  •  mapMutations 函数接收一个对象作为参数,对象中的每个 key 将会转换为一个  methods 函数,对象的 value 与 Vuex 中对应的 mutations 保持映射关系。 mapMutations 返回一个对象,需要解构并且在使用 mutations 生成的函数l时注意传递参数
  •  mapActions 函数接收一个对象作为参数,对象中的每个 key 将会转换为一个  methods 函数,对象的 value 与 vuex 中对应的 actions 保持映射关系。 mapActions 返回一个对象,需要解构并且在使用  actions 生成的函数时注意传递参数

mapMutations 和 mapActions 的第二种写法

<template>
  <div>Demo</div>
  <div>vuex中的state数据 {{num}}</div>
  <div>vuex中的getters中加工了的数据 {{bigSum}}</div>
  <div>
    <button @click="INCREMENT(1)">调用 commit 触发 mutations 中的函数</button>
    <button @click="incrementWait(10)">调用 dispatch 触发 actions 中的函数</button>
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex'
export default {
  computed: {
    ...mapState(['num']),
    ...mapGetters(['bigSum'])
  },
  methods: {
    ...mapMutations(['INCREMENT']),
    ...mapActions(['incrementWait'])
  },
}
</script>
  •   mapMutations 函数接收一个数组作为参数时,数组中的每一个字符串与 Vuex 中对应的 mutations 保持映射关系
  •  mapActions 函数接收一个数组作为参数时,数组中的每一个字符串与 Vuex 中对应的 actions 保持映射关系

Vuex模块化

import {createStore} from 'vuex'

// 计算相关的vuex模块
const calculate = {
  namespaced: true, // 开启命名空间
  state: { // 存放数据地方
    num: 1
  },
  mutations: { // 存放修改数据的地方
    INCREMENT(state, payload) {
      state.num += payload
    }
  },
  actions: { // 存放触发 mutations 的地方
    incrementWait(context, payload) {
      setTimeout(() => {
        context.commit('INCREMENT', payload)
      }, 1000)
    }
  },
  getters: { // 基于 state 数据进行加工的地方
    bigSum(state) {
      return state.num * 10
    }
  }
}
// 员工相关的 vuex 模块
const staff = {
  namespaced: true, // 开启命名空间
  state: {
    person: ['zhangsan']
  },
  mutations: {
    ADDPERSON(state, payload) {
      state.person[0] = payload
    }
  },
  actions: {
    addPersonWait(context, payload) {
      setTimeout(() => {
        context.commit('ADDPERSON', payload)
      }, 1000)
    }
  },
  getters: {
    changePerson(state) {
      return state.person[0] + '666'
    }
  }
}
// 创建一个 store 实例
const store = createStore({
  modules: { // 配置模块
    calculate, // 计算模块
    staff, // 员工模块
  }
})

// 暴露
export default store
  •  namespaced: true 用于开启命名空间
  •  modules 选项中配置模块

 

<template>
  <div>Demo</div>
  <div>计算模块中的state 和 getters {{num}} ---- {{bigSum}}</div>
  <div>
    <button @click="INCREMENT(1)">修改计算模块中的 state </button>
    <button @click="incrementWait(66)">异步修改计算模块中的 state </button>
  </div>
  <div>员工模块中的state 和 getters {{person}} --- {{changePerson}}</div>
  <div>
    <button @click="ADDPERSON('王五')">修改员工模块中的 state</button>
    <button @click="addPersonWait('张三')">异步修改员工模块中的 state</button>
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex'
export default {
  computed: {
    // 使用指定模块中暴露的 state 数据
    ...mapState('calculate', ['num']),
    ...mapState('staff', ['person']),
    // 使用指定模块中暴露的 getters 数据
    ...mapGetters('calculate', ['bigSum']),
    ...mapGetters('staff', ['changePerson']),
  },
  methods: {
    // 使用指定模块中暴露的 mutations 方法
    ...mapMutations('calculate', ['INCREMENT']),
    ...mapMutations('staff', ['ADDPERSON']),
    // 使用指定的模块中暴露的 actions 方法
    ...mapActions('calculate', ['incrementWait']),
    ...mapActions('staff', ['addPersonWait'])
  },
}
</script>
  •  mapState 、 mapGetters 、 mapMutations 、 mapActions 的第一个参数用于指定 vuex 的模块空间,第二个数组中用于指定映射哪些内容
  • 如果不使用这四个辅助函数则写法上有点麻烦
  • 取计算模块中的 state  this.$store.state.calculate.num 
  • 取计算模块中的 getters  this.$store.getters['calculate/bigSum'] 
  • 使用计算模块中的 mutations  this.$store.commit('calculate/INCREMENT', 1) 
  • 使用计算模块中的 actions  this.$store.dispatch('calculate/incrementWait', 50) 

Component API 中使用 Vuex

<template>
  <div>Demo</div>
  <div>计算模块中的state 和 getters {{num}} ---- {{bigSum}}</div>
  <div>
    <button @click="increment(1)">修改计算模块中的 state </button>
    <button @click="incrementWait(66)">异步修改计算模块中的 state </button>
  </div>
  <div>员工模块中的state 和 getters {{person}} --- {{changePerson}}</div>
  <div>
    <button @click="ADDPERSON('王五')">修改员工模块中的 state</button>
    <button @click="addPersonWait('张三')">异步修改员工模块中的 state</button>
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions, useStore, } from 'vuex'
import {computed} from "vue";
export default {
  setup() {
    const store = useStore()
    return {
      num: computed(() => store.state.calculate.num), 
      bigSum: computed(() => store.getters["calculate/bigSum"]),
      increment: (num) => store.commit('calculate/INCREMENT', num),
      incrementWait: (num) => store.dispatch('calculate/incrementWait', num)
    }
  },
  computed: {
    // 使用指定模块中暴露的 state 数据
    ...mapState('staff', ['person']),
    // 使用指定模块中暴露的 getters 数据
    ...mapGetters('staff', ['changePerson']),
  },
  methods: {
    // 使用指定模块中暴露的 mutations 方法
    ...mapMutations('staff', ['ADDPERSON']),
    // 使用指定的模块中暴露的 actions 方法
    ...mapActions('staff', ['addPersonWait'])
  },
}
</script>

 

posted @ 2022-01-31 23:02  霸哥yyds  阅读(739)  评论(1)    收藏  举报