Как взаимодействовать между компонентами через Promise?

Как из одного компонента после после отправки запроса внутри него вернуть результат промиса (resolve/reject), чтобы в другом компоненте обработать его через then? Компоненты при этом могут находиться не рядом и не иметь общего родителя.
  • Вопрос задан
  • 229 просмотров
Решения вопроса 1
MrDecoy
@MrDecoy
Верставший фронтендер
Как из одного компонента после после отправки запроса внутри него вернуть результат промиса (resolve/reject), чтобы в другом компоненте обработать его через then

Ну нужно значит вернуть Promise или Promise.resolve(response). (хотя это что-то сомнительное)

Компоненты при этом могут находиться не рядом и не иметь общего родителя.

Ну, на этот случай есть 2 основных подхода.
1) Глобальное хранилище - vuex.
1.1) Инициализируете стор
1.2) В компоненте, которому нужны данные - делаете вычисляемое свойство на свойство стора.
1.3) В компоненте, в котором делаете запрос - кладёте в then данные из ответа в стор в соответствующее свойство по средствам экшена(ну или мутации на худой конец). (Одна из практик делать запрос данных в экшене, тогда в экшене по результату выполнения запроса и вызовете мутацию для изменения стора, а в компоненте просто вызовете экшен)

2) Глобальная шина событий EventBus (считается сомнительным паттерном) - Один компонент подписывается на событие с произвольным именем - второй компонент диспатчит событие с произвольным именем и передаёт полезную нагрузку. В итоге компонент-подписчик в обработчике получит эти данные.

Независимо от подхода, не нужно в компоненте потребителе обрабатывать через then. Компоненты должны реагировать только на изменение поступающих данных, но не на состояние промиса другого компонента.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@GrayHorse
А не лучше иметь фукцию, которая будет делать запрос и отбрабатывать результат и записывает его в реактивную переменную?

Один компонент вызывает эту функцию.

Другой же компонет использует эту реактивную переменную для своих целей. ("Зависит от нее")

Демо: https://sfc.vuejs.org/#eyJBc...

core.js
import {ref, readonly} from "vue";

const todo = ref(null);
const todoId = ref(1);

export async function fetchTodo() {
  const resp = await fetch("https://jsonplaceholder.typicode.com/todos/" + todoId.value++);
  todo.value = await resp.json();
};

// Using of `readonly` is optional, I use it just in case.
// You can just export `todoId`, `todo` (above) as is.
const _todoId = readonly(todoId);
const _todo   = readonly(todo);
export {
  _todoId as todoId,
  _todo   as todo
};


App.vue
<template>
  <Button/>
  <div v-if="todo">
    {{todo}}
  </div>	
</template>

<script setup>
  import Button from "./Button.vue";
  import {todo} from "./core.js";
</script>


Button.vue
<template>
  <button @click="fetchTodo">fetchTodo({{todoId}})</button>  
</template>

<script setup>
  import {fetchTodo, todoId} from "./core.js";
</script>
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы