欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在路由守卫之前拿到vuex中异步请求数据——vuex中watch方法

程序员文章站 2022-07-03 18:18:37
vuex中watch的使用问题:在全局路由守卫中想要通过store拿到异步请求的数据,无法拿到。我们常见使用vuex,一般是这样的:store模块文件写相关的数据信息,模块一test.js:export default { state: { obj: { count: 2 } }, mutations: { add(state){ return state.obj.count + 1 } }, actions: {...
vuex中watch的使用

问题:在全局路由守卫中想要通过store拿到异步请求的数据,无法拿到。

我们常见使用vuex,一般是这样的:

store模块文件写相关的数据信息,模块一test.js:

export default {
  state: {
    obj: {
      count: 2
    }
  },
  mutations: {
    add(state){
      return state.obj.count + 1
    }
  },
  actions: {
    add({commit}){
      commit('add')
    }
  },
  getters: {
    getCount(state){
      return state
    }
  },
  modules: {
  }
}

导出为test,在store文件夹index.js中引入:

import Vue from 'vue'
import Vuex from 'vuex'
import test from './test'
Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        test
    }
});

在组件内使用:
方式一:

this.$store.state.test.obj.count   // 拿到state中的值
this.$store.commit('add')    // 通过mutations修改state,mutations必须是同步函数
this.$store.dispatch('add')   // 通过actions 异步修改state
this.$store.gettters.getCount   // 通过getters获取state,可以在这里对state里的值先计算,相当于是computed,有缓存作用。

方式二:

// 使用辅助函数
// 在组件中引入
import {mapState, mapActions, mapGetters, mapMutations} from 'vuex';
// 使用

// 因为mapActions是将actions里的函数映射为方法,所以我们写到methods里
methods: {
    ...mapActions(['add','xxx']),   // 通过mapActions访问store中actions里的add方法,如果导出和store里的方法同名,可以使用数组的方式
    // mapMutations 辅助将组件中的methods中的increment函数映射为this.$store.commit('increment')调用
    ...mapMutations(['increment', 'xxx'])
}
// 将具有计算属性功能的mapGetters写在computed里
computed: {
    ...mapGetters(['getCount', 'xxx']),
    ...mapState(['count']),      // mapState 辅助生成计算属性, 可以映射组件中computed中的属性this.count 为 store.state.count
    count() {
        return 10000
    }
}

突然我想要如果在路由加载之前拿到vuex中的数据,比如actions中获取的异步请求数据,能不能拿到?
于是路由守卫函数:

export function addMiddlewares(router, store) {
    router.beforeEach((to, from, next) => {
        console.log(store.state.test.obj.count)
        // ......
        next();
    });
}

在路由导出路由表router的js文件中引入addMiddlewares方法传入router,store:

addMiddlewares(router, store);

发现以上打印不出count,于是在路由表router的js文件中打印,也无法获取count值(得到的永远是state中定义的初始值)。但是打印console.log(store.state.test)却能够在test模块中找到异步获取的count值。

也就是说有个时间关系,路由载入的时候拿不到vuex异步请求信息。

这时候如果能够监听vuex中某个值的变化就好了。

于是经过window.addEventListener等尝试都不行之后,找到vuex官网发现vuex上有个watch方法。

watch*: watch(fn: Function, callback: Function, options?: Object): Function
响应式地侦听 fn 的返回值,当值改变时调用回调函数。fn 接收 store 的 state 作为第一个参数,其 getter 作为第二个参数。最后接收一个可选的对象参数表示 Vue 的 vm.$watch 方法的参数。
要停止侦听,调用此方法返回的函数即可停止侦听。

在addMiddlewares方法中:

function addMiddlewares(router, store) {

    store.watch((state, getters) => getters.getCount.obj.count, (count) => {
        console.log(count);
    });
    //store.watch((state, getters) => state.test.obj.count, (count) => {
    //    console.log(count);
    //});

    router.beforeEach((to, from, next) => {
        // ......
        next();

  });

}

watch第一个函数参数为state, getters,返回正在监听的值;第二个函数返回被监听的值。
当第一个函数返回值为字符串拼接时,第二个函数有第二个参数时,第一个参数count对应的是拼接的监听值,第二个参数val对应的是进行拼接的字符串:

store.watch((state, getters) => getters.getCount.obj.count + 'hahahah', (count, val) => {
    console.log(count);  // 改变后(被重新赋值)的count值
    console.log(val);  // hahahah
});

如果是/``*``%运算符,则第二个参数val对应返回值为0.

store.watch((state, getters) => getters.getCount.obj.count * 5, (count, val) => {
    console.log(count);  // 改变后(被重新赋值)的count值
    console.log(val);  // 0
});

使用watch就可以拿到请求数据后的值,这里需要注意的是,如果state中的数据没有变化,就不会调用回调函数,就拿不到state/getters中的值。

本文地址:https://blog.csdn.net/qq_26769677/article/details/107297316