axios 拦截器与 vuejs 自定义组件集成,用于以通用方式显示错误消息

Posted

技术标签:

【中文标题】axios 拦截器与 vuejs 自定义组件集成,用于以通用方式显示错误消息【英文标题】:axios interceptors integration with vuejs custom components for displaying error messages in a generic way 【发布时间】:2018-10-12 11:12:54 【问题描述】:

假设我们有以下代码

axios.interceptors.response.use(function (response) 
  return response;
, function (error) 
  if (error.response.status === 400) 
    if (error.response.data.type === "fieldsValidationErrors") 
      openModal(modal.validationsFailedInfo);
     else 
      openModal(modal.cannotHandleServerResponse);
    
   else if(error.response.status === 403) 
    redirectToLoginScreen();
   else 
    openModal(modal.errorOccurred);
  
  return Promise.reject(error);
);

此代码之前包含

const app1 = new Vue(...);
app1.init();

我还有另一个 UI 应用:

const app2 = new Vue(...);
app2.init();

在声明 vue 实例之前声明 axios 拦截器。

在每个 vue 应用程序中,我都有一个 <notifications type="danger" :messages="errors.items"></notifications> 组件,用于接收来自应用程序的错误。

在我拥有的notifications 组件内

Vue.component('notifications', 
  ...
  template: '<section v-if="messages.length > 0" id="notifications" class="notifications-outer-wrapper">\n' +
    '    <div class="user-notification-content well form-group" :class=" \'notify-danger\': type === \'danger\', \'notify-success\': type === \'success\' ">\n' +
    '      <span class="fa fa-info-circle notificationIcon" aria-hidden="true"></span>\n' +
    '      &nbsp;\n' +
    '      <span v-if="type === \'danger\'">message</span>\n' +
    '    </div>\n' +
    '  </section>'
);

目前我正在使用模式来显示出现问题。我需要的是在&lt;notifications&gt; 组件内显示一条错误消息,每个 Vue 实例都有一个通知组件。

关于如何获得这种行为的任何想法?

【问题讨论】:

这真的取决于这个拦截器是在哪里定义的。它可以访问 Vue 组件吗?如果有,那么只需为&lt;div&gt; 元素分配ref 属性,然后通过vm.$refs.&lt;something&gt; 选择器设置其内部html。你能创建一个最小的、具体的和可验证的例子吗?见how to ask 和how to create a minimal, concrete and verifiable example (MCVE)。 @Terry Does it have access to the Vue component?是什么意思 我不确定你提到的&lt;div&gt; 元素在哪里。它在组件的模板中吗?标记中的其他位置?无论如何,您的问题中的信息不足无法帮助我们准确诊断您的问题或提供帮助。请更新您的问题。 @Terry 我已经更新了最初的问题。开发一个真实的工作示例将花费我太多时间,我认为我在这一点上提供的内容足以概述我在我的案例中所拥有的内容。 我创建了一个简单的middleware service for axios,您可以在其中以通用方式触发消息。 【参考方案1】:

您可以使用global event bus 在不同的实例之间进行通信。

// create a new Event Bus Instance
$eventBus = new Vue();

// set $eventBus as global Vue variable
// has to be done before new Vue(el: ...)
// after this, $eventBus instance can be acessed using this.$eventBus in all Vue components
Vue.prototype.$eventBus = $eventBus;

axios.interceptors.response.use(function(response) 
    return response;
, function(error) 
    // ...

    // on error, emit an open modal event, add pass message as payload
    $eventBus.emit('open-modal', 
        type: 'error',
        message: '...'
    );
);

Vue.component('notifications', 
    created() 
        // listen to open-modal event
        this.$eventHub.$on('open-modal', (
            type,
            message
        ) => 
            // logic for opening modal, etc...
        );
    ,
    beforeDestroy() 
        this.$eventHub.$off('open-modal');
    ,
);

const app1 = new Vue( /* ... */ );
const app2 = new Vue( /* ... */ );

【讨论】:

以上是关于axios 拦截器与 vuejs 自定义组件集成,用于以通用方式显示错误消息的主要内容,如果未能解决你的问题,请参考以下文章

全局axios默认值 和 自定义实例默认值

ATP应用测试平台——关于axios的配置使用

基于axios请求封装的vue应用

从相同的 axios 到不同的组件,VueJS

在 vuejs 组件中获取 axios base url 的值

如何将变量从 axios 获取请求传递给 vuejs 中的子组件?