Интеграция перехватчиков axios с пользовательскими компонентами vuejs для общего отображения сообщений об ошибках. - PullRequest
0 голосов
/ 02 мая 2018

Предположим, у нас есть следующий фрагмент кода

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();

У меня также есть другое приложение для пользовательского интерфейса:

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

Перехватчики axios объявляются до объявления экземпляров vue.

Внутри каждого приложения 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>'
});

В настоящее время я использую модалы, чтобы показать, что что-то пошло не так. Мне нужно отобразить сообщения об ошибках внутри компонента <notifications>, каждый экземпляр Vue имеет один компонент уведомления.

Есть идеи о том, как получить такое поведение?

1 Ответ

0 голосов
/ 02 мая 2018

Вы можете использовать глобальную шину событий для связи между отдельными экземплярами.

// 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({ /* ... */ });
...