如何在主Vue实例中等待ajax调用?

3

我目前有一个VueJS组件,用于像这样向GitHub进行Ajax调用:

(子)组件

Vue.http.get('user/repos').then((response) => {
    console.log(response);
}, (response) => {
    console.log(response);
});

问题在于,在进行此ajax调用之前,我需要首先获取访问令牌。这个访问令牌存储在数据库中,因此我的主Vue组件正在进行ajax调用以将通用标头设置为所有ajax调用: 主Vue实例
Vue.http.headers.common['Authorization'] = `token ${this.token}`;

const app = new Vue({
    el: '#app',

    data: {
      token: ''
    },

    created() {
        Vue.http.get('/token').then((response) => {
            this.token = response.data.token;
        }, () => {
            console.log('failed to retrieve the access token for the logged in user.');
        })
    }
});

我如何确保在从我的组件运行ajax调用之前,已成功设置“Authorization”标头的ajax调用?


1
为它设置一个“watch”? - Amresh Venugopal
@AmreshVenugopal 真的很简单,我甚至没有想过。谢谢! - Stephan-v
2个回答

5

为了帮助其他可能受益的人,我在这里添加了这段内容。

  1. Get the token from the API call, add it up in a vuex state variable.

  2. Access the same using a getter in the child component, as a computed property or you can pass it on as props or via an event bus but both the ways are not as powerful as using vuex.

  3. watch over the property, and perform your required action when the token is obtained.

    // Add this up in the child component
    
       computed: {
         ...mapGetters({
            token: <name-of-the-getter> // token becomes the alias for the computed
         })                            // property.
       },
    
       watch: {
         token () {
           if(this.token) this.someAPICall()// or some other applicable condition
         }
       },
    
       methods: {
         ...mapActions({
           someAPICall: <name-of-the-action>
         })
       }
    
    // ----------------------------------------------
    

观察需要值的变化,我注意到在一个操作中提交的更改会导致 watch 触发。因此,如果由于某种原因令牌丢失或过期,您自然无法进行后续请求。

编辑

import store from 'path/to/store'

axios.interceptors.response.use(function (response) {
  // extract the token from the response object
  // save the token to the store for access during subsequent
  // requests.
  return response;
}, function (error) {
  // Do something with response error
  return Promise.reject(error);
});

axios.interceptors.request.use(function (config) {
  // use store getters to access token
  return config;
}, function (error) {
  // Do something with request error
  return Promise.reject(error);
});

有什么想法可以处理需要令牌的许多地方吗?在所有页面上重复代码还是创建路由守卫? - Rodrigo Saling
我使用axios拦截器和存储来处理这种情况。你需要一个例子吗? - Amresh Venugopal

1

您可以通过自己的函数替换/代理Vue.http.get函数,该函数将首先请求令牌,然后执行您的请求,大致思路如下:

!function() 
{ 
  var vue_http_get = Vue.http.get;
  var token = null;

  // patching/proxying Vue.http.get function   
  Vue.http.get = function get() {
    vue_http_get.apply(Vue.http,"path/to/get/token/").then(function(resp){
      token = resp; 
      Vue.http.headers.common['Authorization'] = ...;
      // putting back original Vue.http
      Vue.http = vue_http_get;
      return Vue.http.get(arguments[0]);
    });
  }; 
}();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接