vue多个组件中如何监听vuex中同一个action的回调

vue单页面应用,在整个app入口,需要调用获取用户信息的接口,这个接口只调用一次,怎样能够在多个组件中获取到这个接口完成的通知。

app.vue

  export default {
    mounted() {
      this.userInfo().then(res => {
        if (res.code === 200) {
            // 具体的操作
        }
      });
    },
    methods: {
      ...mapState(['userInfo'])
    }
  };

其他组件 在mounted 获取不到userInfo

export default {
    mounted() {
        this.userInfo // 这里获取用户信息为空,怎样能获取到用户信息呢
    },
    methods: {
      ...mapState(['userInfo'])
    }
  };

已尝试的解决方案。
第一种通过$watch监听userInfo

watch: {
      userInfo(newValue){
        if(newValue.username){
          // 具体执行函数
        }
      }
    },

第二种 在入口处用loading状态来控制,当在入口处action结束时,通过v-if控制渲染,
这样存在的问题是当这个接口挂了,整个页面都是空白的

  <div id="app">
    <template v-if="loading">
       <router-view class="child-view"></router-view>
    </template>
  </div>   
 export default {
    data(){
      return {
        loading:false  
      }
    },
    mounted() {
      this.userInfo().then(res => {
          this.loading=true
      })
    },
    methods: {
      ...mapState(['userInfo'])
    }
  }

想问一下,有其他更好的办法吗?

阅读 7.9k
4 个回答

用计算属性就可以了,当userinfo更新时会自动触发组件数据更新

computed: {
    ...mapState({
        userInfo: state => state.userInfo
    }),
},

可以用getter,vuex的实时计算state

async UPDATE_USERINFO (context) {
    const userinfo = await fly.get('/my/setting/personal/loadUserInfo').catch(e => {
      console.log(e)
    })
    context.commit('SET_USERINFO', userinfo.data)
},

路由代码
if (to.meta.requiresAuth) {
    if (token) {
      if (store.state.userInfo) {
        next()
      } else {
        store.dispatch('UPDATE_USERINFO').then(() => {
            next()
          }
        )
      }
    } else {
      title = '账号关联'
      next({
        path: '/login',
      })
    }
  } else {
    next()
  }

你可能 还需要一个 小工具

https://github.com/qinouz/vue... 若果又用请star

找到解决办法了,创建一个变量保存promise,如果多个组件同时发出请求,第一个请求赋值给该变量,其他情况直接返回该变量,具体看代码吧。

let getUserPromise = null;
let isLoading      = false;
const actions      = {
  GET_USREINFO({ commit, state }) {
    if (state.userInfo.username) {
      // 如果存在用户信息,直接返回
      return Promise.resolve({
        code: 200,
        msg: 'ok',
        result: state.userInfo
      });
    } else {
      if (!isLoading) {
        isLoading = true;
        if (!getUserPromise) {
          getUserPromise = useSrv.getUserInfo().then((res) => {
            // 具体业务逻辑
            getUserPromise = null; // 重置,保证下次调用
            return res;
          }).finally(() => {
            isLoading = false;
          });
        }
      }
      return getUserPromise;
    }
  }
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题