下面讲解不举例子,只总结基本使用
1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
多个组件需要共享数据时
(1)创建store文件:src/store/index.js
- //引入Vue核心库
- import Vue from 'vue'
- //引入Vuex
- import Vuex from 'vuex'
- //应用Vuex插件
- Vue.use(Vuex)
-
- //准备actions对象——响应组件中用户的动作
- const actions = {}
- //准备mutations对象——修改state中的数据
- const mutations = {}
- //准备state对象——保存具体的数据
- const state = {}
-
- //创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state
- })
(2)在main.js文件中创建vm时船传入store配置项
- ......
- //引入store
- import store from './store'
- ......
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App),
- store
- })
- ```
1. 初始化数据、配置state、actions、mutations,操作文件store.js
- //引入Vue核心库
- import Vue from 'vue'
- //引入Vuex
- import Vuex from 'vuex'
- //引用Vuex
- Vue.use(Vuex)
-
- const actions = {
- //响应组件中加的动作
- jia(context,value){
- // console.log('actions中的jia被调用了',miniStore,value)
- context.commit('JIA',value)
- },
- }
-
- const mutations = {
- //执行加
- JIA(state,value){
- // console.log('mutations中的JIA被调用了',state,value)
- state.sum += value
- }
- }
-
- //初始化数据
- const state = {
- sum:0
- }
-
- //创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state
- })
2.组件中读取vuex中的数据:$store.state.sum
3.组件中修改vuex中的数据:$store.dispath('action中的方法名',数据),或 $store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接
编写commit
(1)概念:当state中的数据需要经过加工后再使用时,可以使用getters加工
(2)在store.js中追加getters配置
(3)组件中读取数据:$store.getters.bigSum
- const getters = {
- bigSum(state){
- return state.sum * 10
- }
- }
-
- //创建并暴露store
- export default new Vuex.Store({
- ......
- getters
- })
1. mapState方法:用于帮助我们映射state中的数据为计算属性
computed: {
//借助mapState生成计算属性:sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'}),
//借助mapState生成计算属性:sum、school、subject(数组写法)
...mapState(['sum','school','subject']),
},
2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性
computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
},
3. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数
```js
methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//靠mapActions生成:incrementOdd、incrementWait(数组形式)
...mapActions(['jiaOdd','jiaWait'])
}
4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数
```js
methods:{
//靠mapActions生成:increment、decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
//靠mapMutations生成:JIA、JIAN(对象形式)
...mapMutations(['JIA','JIAN']),
}
> 备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂时,store对象就有可能变得相当臃肿。
为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
命名空间的作用:
默认情况下,模块内部的action和mutation仍然是注册在全局命名空间的——这样使得多个模块能够对同一个action或mutation作出响应。Getter同样也默认注册在全局命名空间,但是目前这并非处于功能上的目的(仅仅是维持现状来避免非兼容性变更)。必须注意,不要在不同的、无命名空间的模块定义两个相同的getter从而导致错误。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加namespaced:true的方式使其成为带命名空间的模块,当模块被注册后,它的所有getter、action及mutation都会自动根据模块注册的路径调整命名。
这里不做过多赘述,可以自己去看vuex官方文档
注意:
作者在测试命名空间namespaced的继承性的时候,发现嵌套模块并未继承父模块的namespaced值。
1. App.vue
- <template>
- <div class="app">
- <component-a>component-a>
- <component-b>component-b>
- <hr>
- div>
- template>
- <script>
- import ComponentA from "./components/ComponentA.vue";
- import ComponentB from "./components/ComponentB.vue";
- export default {
- name: "App",
- components: {
- ComponentA,
- ComponentB
- },
- data() {
- return {
-
- }
- },
- methods: {
-
- }
- }
- script>
2. moduleA.js
- const moduleA = {
- // namespaced: true,
- state: {
- sum: 0
- },
- mutations: {
- addSum(state,value) {
- state.sum = state.sum + value
- console.log("moduleA.addSum",state,value)
- },
- subSum(state,value) {
- state.sum = state.sum - value
- console.log("module.A.subSum",state,value)
- }
- },
- actions: {
- ADDSUM(context,value) {
- console.log("moduleA.ADDSUM",context)
- context.commit("addSum",value)
- },
- SUBSUM(context,value) {
- console.log("moduleA.SUBSUM",context)
- context.commit("subSum",value)
- }
- },
- getters: {
- getSum(state,getters,rootState) {
- console.log("getters",getters)
- console.log("root",rootState)
- return state.sum * 2
- }
- }
- }
- export default moduleA
3. moduleB.js
- const moduleB = {
- namespaced: true,
- state: {
- schoolName: "南昌大学",
- schoolAddress: "江西省南昌市"
- },
- getters: {
- // 学校信息
- getSchoolInfo(state) {
- return state.schoolName + '---' + state.schoolAddress
- }
- },
- mutations: {
- },
- actions: {
- },
- modules: {
- classRoom: {
- namespaced: false,
- state: {
- classRoomName: "一年二班",
- classRoomPersons: 64
- },
- getters: {
- getClassInfo(state) {
- return state.classRoomName + '---' + state.classRoomPersons
- }
- }
- }
- }
- }
- export default moduleB
4.index.js(store暴露文件)
- import Vue from "vue";
- import Vuex from "vuex";
- import moduleA from "./moduleA.js";
- import moduleB from "./moduleB";
-
- Vue.use(Vuex)
- // 应用Vuex插件
- export default new Vuex.Store({
- modules: {
- a: moduleA,
- school: moduleB
- }
- })
5. 组件组件ComponentA.vue
- <template>
- <div class="component-a">
- <h1>当前求和为:{{ sum }}h1>
-
- <button @click="increment(1)">Action++button>
- <button @click="decrement(1)">Action--button>
- <button @click="addSum(1)">Mutation++button>
- <button @click="subSum(1)">Mutation--button>
- div>
- template>
-
- <script>
- import { mapGetters, mapActions,mapMutations, mapState } from 'vuex'
- export default {
- name: "component-a",
- data() {
- return {
- }
- },
- computed: {
- // ...mapState('a',['sum']),
- ...mapState({
- sum: state => state.a.sum
- }),
- // ...mapGetters('a',['getSum'])
- },
- methods: {
- // ...mapMutations('a',{ addSum: 'addSum',subSum: 'subSum' }),
- // ...mapActions('a',{ increment: 'ADDSUM',decrement: 'SUBSUM' })
- increment(value) {
- // 如果开启了命名空间
- // this.$store.dispatch("a/ADDSUM",value)
- // 如果没开启命名空间
- this.$store.dispatch("ADDSUM",value)
- },
- decrement(value) {
- // this.$store.dispatch("a/SUBSUM",value)
- this.$store.dispatch("SUBSUM",value)
- }
- },
- mounted() {
- console.log("this.$store",this.$store)
- }
- }
- script>
-
- <style>
- .component-a {
- padding: 40px 40px;
- }
- style>
6. 组件ComponentB.vue
- <template>
- <div class="component-b">
- <h2>学校信息h2>
- <h3>学校名称:{{ schoolName }}h3>
- <hr>
- <h2>教室信息h2>
- <h3>教室名:{{ classRoomName }}h3>
- <h3>教师学生数量:{{ classRoomPersons }}h3>
- div>
- template>
-
- <script>
- import { mapState } from 'vuex';
- export default {
- name: "component-b",
- data() {
- return {
-
- }
- },
- computed: {
- ...mapState('school',['schoolName','schoolAddress']),
- // 给classRoom模块开启命名空间才能使用这种导入state方式
- // ...mapState('school/classRoom',['classRoomName','classRoomPersons'])
- // 开启命名空间与否都可以使用这种导入state方式
- ...mapState({
- classRoomName: state => state.school.classRoom.classRoomName,
- classRoomPersons: state => state.school.classRoom.classRoomPersons
- })
- }
- }
- script>
-
- <style>
- .component-b {
- padding: 0 40px;
- }
- style>