Как получить доступ к корневому контексту из функции композиции в Vue Composition API / Vue 3.0 + TypeScript? - PullRequest
0 голосов
/ 27 октября 2019

Я хочу создать повторно используемую функцию-обертку , написанную на TypeScript для запуска уведомления о тосте с использованием составной функции , как определено в текущей спецификации дляVue 3.0: Состав API API RFC .

В этом примере используется компонент tots BootstrapVue v2.0. При использовании Vue 2 он будет вызываться с помощью this.$bvToast внедрения экземпляра компонента Vue в корневом контексте :

this.$bvToast.toast('Error happened', {
  title: 'Oh no',
  variant: 'danger'
});

Эта сервисная функция компоновки будет выглядеть примерно так:

// File: @/util/notify.ts
export function useNotify() {
  const notifyError = (title: string, msg: string) => {
    // How to access context.root as in a function component, without passing it to this function?
    context.root.$bvToast.toast(msg, {
      title,
      variant: 'danger'
    });
  };

  return { notifyError};
}

export default useNotify;

И будет использоваться так:

// Use in your functional component:
import { createComponent } from '@vue/composition-api';

import { useNotify} from '@/util/notify';

export default createComponent({
  name: 'MyFailingComponent',
  setup() {
    const { notifyError } = useNotify();

    notifyError('Request error', 'There was an error processing your request, please try again later.');

    return {};
  }
});

1 Ответ

1 голос
/ 27 октября 2019

Ну, я скоро нашел подходящий пример на том же сайте RFC. Но решил поделиться своими примерами здесь.

На данный момент сайт RFC не содержит примеров в TypeScript, для ясности, я полагаю. Поскольку этот новый способ написания компонентов и композиционных функций Vue 3.0 (в качестве замены Mixins) требует некоторого привыкания.

Ответ: Вы можете передать объект контекста непосредственно в функцию композиции, когдаобъект-деструктурирование необходимых частей в коде вашего компонента.

// File: @/util/notify.ts
import { SetupContext } from '@vue/composition-api';

export function useNotify(context: SetupContext) {
  const notifyError = (title: string, msg: string) => {
    context.root.$bvToast.toast(msg, {
      title,
      variant: 'danger'
    });
  };

  return { notifyError};
}

export default useNotify;
// Use in your functional component:
import { createComponent, SetupContext } from '@vue/composition-api';

import { useNotify} from '@/util/notify';

export default createComponent({
  name: 'MyFailingComponent',
  setup(props: any, context: SetupContext) {
    const { notifyError } = useNotify(context);

    notifyError('Request error', 'There was an error processing your request, please try again later.');

    return {};
  }
});

То же самое с использованием типов TypeScript с деструктуризацией сложного объекта при передаче нескольких аргументов функции в качестве объекта:

// File: @/util/notify.ts
import { SetupContext } from '@vue/composition-api';

export function useNotify({ context, defaultTitle = 'Hey!' }: { context: SetupContext, defaultTitle?: string }) {
  const notifyError = (msg: string, title?: string) => {
    context.root.$bvToast.toast(msg, {
      title: title || defaultTitle,
      variant: 'danger',
    });
  };

  return {
    notifyError,
  };
}

export default useNotify;

// Usage like:
const { notifyError } = useNotify({ context });
// Or
const { notifyError } = useNotify({ context, defaultTitle: 'Hey there' });

Аккуратный синтаксис, хорошо сделанное сообщество Vue!

...