【问题标题】:How to wait for ajax call from main Vue instance?如何等待来自主 Vue 实例的 ajax 调用?
【发布时间】:2017-01-09 00:21:43
【问题描述】:

我目前有 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 调用之前,设置“授权”标头的 ajax 调用已成功?

【问题讨论】:

  • 为它设置watch
  • @AmreshVenugopal 如此简单。甚至没有考虑过。谢谢!

标签: javascript ajax vue-component vue.js


【解决方案1】:

为其他可能受益的人添加此内容。

  1. 从 API 调用中获取令牌,将其添加到 vuex 状态变量中。

  2. 在子组件中使用 getter 访问相同的内容,作为计算属性,或者您可以将其作为 props 或通过事件总线传递,但这两种方式都没有使用 vuex 强大。

  3. watch 属性,并在获取令牌时执行您所需的操作。

    // 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 需要更改值,我注意到在操作中所做的提交会导致 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);
});

【讨论】:

  • 当有很多地方需要令牌时,您知道该怎么做吗?在所有页面上重复代码或创建路由保护?
  • 我使用 axios 拦截器和存储来处理这种情况。你想要一个例子吗?
【解决方案2】:

你可以用你自己的函数替换/代理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]);
    });
  }; 
}();

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2018-06-09
    相关资源
    最近更新 更多