Vuex状态管理(上)

Vuex状态管理(上)

一.概念

vue官方提供的状态管理器.用于处理全局的数据共享问题的.

​ 状态:即数据、视图。状态管理的本质,就是对应用程序的数据进行科学地流程化管理,目标是让数据变化可预期、可控。Flux一种数据管理架构方案,这是一种数据管理的思想,最早诞生于React团队。

  • React技术栈中,最出名的状态管理工具是 Redux和Mobx。
  • Vue技术栈中,最出名的状态管理工具是Vuex。

Vuex只是一种数据管理方案,并不是Vue开发必须的。换句话说,在架构Vue项目时可以不使用Vuex。
虽然可以不使用Vuex,但不得不说Vuex非常强大,所以还是建议尽量用上它。Vuex常用于实现组件之间的数据交互、程序数据缓存等需求。Vuex配合devtools,可以非常方便地调试应用程序中的数据bug。

之前我们学习Vue的时候,各种组件之间传值,比如props传值,状态提升传值,事件总线,还有通过emit事件回传等等.那我们这里引入的Vuex,就是组件之间数据交互的终极解决方案.

二.Vuex的仓库的五大核心概念

1.state

state是Vuex的数据存储中心

放在state中的数据,所有组件都可以共享,并且保持同步,只要state中的数据发生变化,视图中自动更新页面状态.

2.getters

getters可以理解为组件中的计算属性

放在getters关联的state,只要发生变化,getters 会自动更新

3.mutations

唯一能够修改state数据的东西,不允许写异步代码

mutation直接同步的修改state的主要入口!在组件中使用this.$store.commit(‘已定义的mutaation方法’,‘负载’)来触发mutation方法

4.actions

间接的异步修改state,在actions里面的方法都是异步,比如调接口,定时器等.

实际上在actions中可以直接修改state,但是这样做在devtools没有修改的记录,非常不方便于调试

vuex官方建议:只用mutations来修改state,不要使用actions来修改state

5.module

仓库模块的拆分

三.安装与使用

1.安装

npm install vuex -S

2.使用

在src目录中新建一个名为store.js的文件,然后引入vue,vuex,并注册vue.use(vuex)

//引入vue
import Vue from 'vue';
//import Vuex
import Vuex from 'vuex';
//注册Vue.use();
Vue.use(Vuex);

const store = new Vuex.Store({
    //Vuex的数据存储中心
    state:{
        
    },
    //组件中的计算属性
    getters:{
        
    },
    //唯一能够修改state数据的东西,不允许写异步代码
    mutations:{
        
    },
    //间接的异步修改state,在actions里面的方法都是异步,比如调接口,定时器等.
    actions:{
        
    },
    //仓库模块的拆分
    modules:{
        
    }
});
export default store;

3.main.js引入并挂载

//引入store
import store from './store';

new Vue({
  router,
  store,//挂载store.js
  render: h => h(App),
}).$mount('#app')

4.验证是否安装成功

console.log(this.$store);

在任何地方,输出this.$store即可,比如App.vue的钩子函数mounted

5.组件中如何使用state和getters

1.方法一

使用挂载到Vue原型上的 s t o r e , store对象,这个 store对象就是new Vuex.Store()生成的仓库实例对象

console.log(this.$store.state.xxxxxx);
console.log(this.$store.getters.yyyyy);
2.方法二(推荐) computed

使用computed,计算属性,实际上就是将方案一中获取到的数据给计算属性

computed: {
    xxxxxx: function() {
      return this.$store.state.xxxxxx;
    },
    yyyy: function() {
      return this.$store.getters.yyyyy;
    }
  },
3. 方法三(推荐) vuex 辅助函数

就是方案二中的一种优雅写法,可以认为是语法糖

组件中从vuex中引入你需要的辅助函数

调用辅助函数,并将其返回的值赋给组件的computed选项

import { mapState, mapGetters } from "vuex";

export default {
  computed: {
    ...mapState(["xxxx", "yyyyy"]),
    ...mapGetters(["culecount"]),
  }
}    

mapState的语法和mapGetters语法

// mapState 接收一个数组做为参数,参数中的每一项,就是在仓库中的 state 数据
mapState([state1, state2, state3])

// mapGetters  接收一个数组做为参数,参数中的每一项,就是在仓库中的 getter 数据
mapGetters([getter1, getter2])

使用计算属性和辅助函数取值时的区别?

二者效果一样,但是在VueDevtools中的表现不一样

使用计算属性时,插件中显示的是computed

使用辅助函数时,插件中显示的是vuexbindings

虽然效果一样,但是我们一般推荐使用辅助函数的形式!!!

 computed: {
    //推荐使用展开运算符
    ...mapState(["count", "msg"]),
    ...mapGetters(["culecount"]),
    xxxxxx: function() {
      return this.$store.state.count;
    },
    yyyy: function() {
      return this.$store.getters.culecount;
    }
  },

6.组件中如何修改state与getters的数据

首先要明确一点:state可以修改,getters是不能被修改的

步骤:

  • 仓库中要提供对应 state修改的mutation函数
  • 在组件中去调用mutation

调用mutationd 的2种方式:

1.方法一

直接使用vuex绑定到vue原型上的$store对象的commit()方法

this.$store.commit()

//在仓库中的 mutations中定义方法
mutations: {
    //在mutation中定义一个改变state里参数的方法
    updateCount(state, payload) {
        state.count += payload.count;
    }
}

 //在相应的组件中触发这个函数
 methods: {
    clickhandle() {
      // 不建议直接改vuex里的state,虽然可以改,但是不建议
      //this.$store.state.count++;
      let payload = {
        count: 10
      };
      // 向store提交一个名叫updateCount的mutation方法,申请同步改变count
      this.$store.commit("updateCount", payload);
    },
 }
2.方法二(推荐) vuex 辅助函数

使用vuex的辅助函数,mapMutations和

   //在仓库中的 mutations中定义方法  
   mutations: {
       updateCount(state, payload) {
           state.count += payload.count;
       },
       updateMsg(state,payload){
           state.msg=payload;
       }
   },
       
   //类似解构赋值
   import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
       
   //在组件中使用vuex辅助函数    
   methods: {
   //推荐使用展开运算符
   ...mapMutations(["updateCount", "updateMsg"]),
   ...mapActions(["asyncUpdateCount", "asyncUpdateMsg"]),
   //因展开运算符展开的方法,无法传参,所以这里可以使用一个函数做中转
   update() {
     let payload = {
       count: 10
     };
     this.updateCount(payload);
   },

所有的mutation执行,都能在VueDevtools看到

为何vuex中的state必须使用mutation来修改呢?

  • 为了以一种可以预见的方式去修改数据,不至于让数据难以理解,虽然可以通过$store对象直接修改,但是在严格模式下会报错,并且VueDevtools无法跟踪到数据,不方便调试
  • 为了实现调试插件(VueDevtools)的时间旅行机制

7.使用actions异步修改state数据

首先要知道,mutation里面只允许同步的去修改state数据,

其实mutation中可以异步的去修改state数据,不会报错,但是会导致调试插件的时间旅行等机制没有效果

处理异步修改state数据有两种方式

  • 1.不涉及action,直接在组件上的methods方法中写异步代码,然后再调用mutation

  • 2.涉及action

    使用action,首先需要在actions选项中定义action函数

    注意:action中不能直接去修改state,要修改state,必须使用当前上下文对象的commit()去执行某个mutation来修改

使用涉及action修改数据的方式也有两种

1.方法一

在仓库中的action中通过commit调用mutation中的方法,然后异步处理,然后在需要调用的组件内部methods选项中,通过 this.$store.dispatch()来派发

 	// actions:间接地异步地修改state
    // 在actions里面的方法,都是异步,比如调接口、定时器等
    // 在actions中可以直接state,但这样做在devtools没有修改的记录,非常不便于调试
    // Vuex官方特别建议,只用mutations来修改state,不要使用actions来修改state
    actions: {
        asyncUpdateCount(store, payload) {
            setTimeout(() => {
                store.commit('updateCount', payload)
            }, 2000);
        }
    }


	//组件中
    methods: {
     clickAsyncHandle() {
      let payload = {
        count: 10
      };
      // 向store提交一个名叫asyncUpdateCount的actions方法,申请异步改变count
      this.$store.dispatch("asyncUpdateCount", payload);
   	 }
    }
2.方法二

使用Vuex中的辅助函数 mapActions

//类似解构赋值
import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; 
methods: {
    ...mapMutations(["updateCount", "updateMsg"]),
    ...mapActions(["asyncUpdateCount", "asyncUpdateMsg"]),
}

使用方式与上面mutation的方法基本一致!

猜你喜欢

转载自blog.csdn.net/liuqiao0327/article/details/106822055