Как получить доступ к функции компонента из main.js в Vue 3 с помощью Composition API

Используя Vue 3 и составной API, у меня есть компонент с этой функцией:

const retrieveSignedJWT = async (callback) => {
  if (jwtUrl.value && !callback) {
    //console.info("There's no callback use the by default URL")
    await fetch(jwtUrl.value)
      .then(async (response) => {
        const data = await response.text();
        // check for error response
        if (!response.ok) {
          // get error message from body or default to response statusText
          const error = (data && data.message) || response.statusText;
          return Promise.reject(error);
        }
        let jwt = data;
        token.value = data;
        decodeToken(jwt);
        retrieveCategories();
      })
      .catch((error) => {
        errorMessage.value = error;
        console.error("There was an error!", error);
      });
  } else {
    //Function has a callback
    token.value = callback;
  }
};

Что мне нужно сделать, так это найти способ показать предыдущую функцию компонента, чтобы я мог вызывать ее из main.js. Сценарий заключается в том, что я создаю IIFFE с Vue 3 и Vite (виджет, который конечный пользователь будет загружать из скрипта) и подключаю к нему общедоступную функцию, чтобы пользователь мог использовать ее в любой точке своего кода. Эта функция может иметь или не иметь обратный вызов, который предоставит реализованный токен.

import { createApp } from "vue";
import "@/assets/styles/index.scss";
import App from "./App.vue";
import store from "./store";
let div = document.createElement("div");
document.body.appendChild(div);
div.setAttribute("id", "my-widget");
window.myWidget = {
  load: function (endUserRetrievedJWT) {
    if (endUserRetrievedJWT) {
      const endUserJWT = endUserRetrievedJWT();
      //Calling my component function w a call back
      retrieveSignedJWT(endUserJWT);
    } else {
      //Calling my component function without a call back 
      retrieveSignedJWT();
    }
  },
};
createApp(App).use(store).mount("#my-widget");

Итак, в основном я пытаюсь найти способ вызвать функцию родительского компонента из файла main.js, чтобы управлять тем, как сохранить токен в состоянии моего приложения. Этот токен может исходить из URL-адреса по умолчанию или в форме функции обратного вызова, которую конечный пользователь передаст в качестве аргумента функции глобального доступа из main.js.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

main.js предназначен для настройки вашего приложения Vue. Не используйте это для любого другого кода! Это не сработает. Просто создайте отдельный файл .js (например, utils.js) и экспортируйте оттуда функцию.

Я не совсем уверен, чего именно вы пытаетесь достичь, но это похоже на процесс аутентификации для входа в систему. Вероятно, вы пытаетесь вызвать функции входа/выхода из компонента Vue? Это может быть так же просто, как

// Separate file, e.g. `authentication.js`
export const login = (cb) => {
  // do not name the callback function (cb) 'callback' as that may get you unexpected behavior
  // Your code
  somePromise().then((res) => {
    cb(res);
  });
}
// Your component
import { login } from 'path/to/authentication';

login(myCallback);

const myCallback = (res) => {
 ...
};

Спасибо, @paddotk. Можно немного развить? Я понимаю, что вместо того, чтобы создавать функцию внутри компонента, я должен создать своего рода «сервис», который экспортирует эту функциональность глобально, а затем вызывает ее из файла main.js. Это правильно? Основная проблема заключается в том, что функция будет получать некоторые данные из компонента.

Lowtrux 10.01.2023 16:41

«Сервис» — это просто отдельный класс javascript. Вы также можете использовать это, но это, вероятно, не обязательно. Подойдет простой файл javascript с экспортированной функцией. Что касается данных, то в функцию можно передавать любые аргументы.

paddotk 10.01.2023 16:43

Это какой-то плагин? Просто пытаюсь найти лучшую практику для этого подхода внутри реализации Vue. Кроме того, я знаю, что могу передать параметры экспортируемой функции, но этот параметр находится в состоянии компонента. Поэтому мне нужно будет иметь доступ к этому состоянию в main.js, когда я запускаю глобально открытую функцию.

Lowtrux 10.01.2023 16:51

Я обновил свой ответ. Не знаю, это ли вы имеете в виду, но, возможно, это поможет

paddotk 11.01.2023 11:56

Спасибо @paddotk, ваш ответ помог мне добраться до финального подхода.

Lowtrux 13.01.2023 10:18
Ответ принят как подходящий

В конце концов я выставил функцию в смонтированном хуке следующим образом:

onMounted(() => {
  window.myWidget = {
    load: retrieveEndUserJWT,
  };
  retrieveDataAttributes();
  callWebsocket(websocket.value);
});

Затем внутри того же компонента я создаю метод, который будет обрабатывать обратный вызов:

const retrieveEndUserJWT = async (endUserRetrievingTokenCallback) => {
  const jwt = await endUserRetrievingTokenCallback();
  processingToken(jwt);
};

И в методе processingToken я имею дело с этим токеном, поступающим от функции обратного вызова конечного пользователя. Мне все еще нужно ориентироваться в плюсах и минусах выставления функции в смонтированном хуке.

Другие вопросы по теме