Как предоставить / внедрить в корневой экземпляр Vue с помощью nuxt и @ vue /position-api?

Я пытаюсь использовать @vue / apollo-composable с моим приложением Nuxt-Ts. Это пример того, как его следует внедрить в корневой экземпляр в обычном приложении Vue:

import { provide } from '@vue/composition-api'
import { DefaultApolloClient } from '@vue/apollo-composable'

const app = new Vue({
  setup () {
    provide(DefaultApolloClient, apolloClient)
  },

  render: h => h(App),
})

Проблема: я не знаю, как получить доступ к корневому экземпляру в Nuxt-TS.

Я попытался создать плагин, но он был введен либо непосредственно в корневой экземпляр (что неверно, потому что @vue/apollo-composable использует _ 3_, который создает собственное свойство _provided.

И если я использую подключаемый модуль nuxt inject, то получается $ конкатенированный. И если я напишу объект _provided напрямую через ctx.app._provided =, он не прижится.

import { DefaultApolloClient } from "@vue/apollo-composable";
const myPlugin: Plugin = (context, inject) => {
  const defaultClient = ctx.app.apolloProvider.defaultClient;
  inject(DefaultApolloClient.toString(), defaultClient) // results in $$ and also composition-api::inject is checking inside `_provided[DefaultApolloClient]`
}

export default myPlugin

Я не могу вызвать provide(), как в исходном примере, потому что это разрешено только внутри VueComponent::setup функции.

Я также попытался создать компонент и просто использовать его на той странице, в которой он мне нужен (хотя это как бы поражает цель установки в корневом экземпляре)

const InstallGraphQl = createComponent({
  name: "InstallGraphQl",
  setup(_props, ctx: any) {
    debugger;
    const apolloClient = ctx.app.apolloProvider.defaultClient;
    ctx.provide(DefaultApolloClient, apolloClient);
  },
});
export default createComponent({
  name: "DefaultLayout",
  components: {
    InstallGraphQl
  },
  setup(_props, _ctx: SetupContext) {
    const { result } = useQuery(SharedLayoutQuery);
    return { result };
  },
});

но затем setup экспортированных компонентов вызывается до _14 _...

Изменить: также для получения дополнительной информации о @vue/apollo-composable см. Обсуждение здесь: https://github.com/vuejs/vue-apollo/issues/687


person JoeSchr    schedule 05.12.2019    source источник


Ответы (3)


Просто установите setup() для корневых параметров:

/* plugins/provide-apollo-client.js */

import {provide} from '@vue/composition-api'
import {DefaultApolloClient} from '@vue/apollo-composable'

export default function ({app}) {
  app.setup = () => {
    provide(DefaultApolloClient, ...)
  }

  // Or, use local mixin
  app.mixins = (app.mixins || []).concat({
    setup () {...},
  })
}
/* nuxt.config.js */

export default {
  plugins: ['~/plugins/provide-apollo-client'],
}

Не очень знаком с nuxt-ts, но я думаю, что код должен просто работать.

person SilentDepth    schedule 10.12.2019
comment
Хотя @Austio направил меня в правильном направлении, вызов provide() внутри моего default.vue::setup() вызвал ошибку нехватки памяти. (Я думаю, потому что он продолжает перезагружаться, потому что я также запрашиваю loggedInUser в моем default.vue) И я также думаю, что размещение provide(DefaultApolloClient,..) внутри его собственного файла, а не в default.vue, является более правильным подходом. - person JoeSchr; 16.12.2019

Я не использую nuxt-ts, но у меня есть эта настройка в приложении nuxt. В моем шаблоне default.vue я предоставляю вот так.

<script>
  import { provide } from '@vue/composition-api';
  import { ApolloClients } from '@vue/apollo-composable'

  export default {
    setup(props, context) {
      provide(ApolloClients, {
        default: context.root.$apollo,
      })
    }
  }
</script>

Версии пакета

"@vue/apollo-composable": "4.0.0-alpha.1"
"@vue/composition-api": "version": "0.3.4"

Установка Аполлона

//apolloClient.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import link from './link';

export default function apolloClient(_, inject) {
  const cache = new InMemoryCache();

  const client = new ApolloClient({
    // Provide required constructor fields
    cache,
    link,
    // Provide some optional constructor fields
    name: 'apollo-client',
    queryDeduplication: false,
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'cache-and-network',
      },
    },
  });

  inject('apollo', client);
}

// link.js
import { split } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import fetch from 'unfetch';
const httpLink = new HttpLink({
  uri: 'http://localhost:8080/v1/graphql',
  credentials: 'same-origin',
  fetch,
});

const wsParams = {
  uri: `ws://localhost:8080/v1/graphql`,
  reconnect: true,
};

if (process.server) {
  wsParams.webSocketImpl = require('ws');
}

const wsLink = new WebSocketLink(wsParams);

// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
const link = split(
  // split based on operation type
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink,
);

export default link;

Затем, используя вышеизложенное, вы включаете apollo в свой nuxtconfig как плагин

  plugins: [
    '~/plugins/vue-composition-api',
    '~/plugins/apolloClient'
  ],
person Austio    schedule 05.12.2019
comment
Спасибо за ответ, кажется, это единственный способ, который в настоящее время работает? Но как настроить apollo? Потому что, хотя я получаю apolloClient по умолчанию, он все еще пуст, а не заполнен моими настройками из nuxt.config.ts. вы используете @ nuxt / vue-apollo для создания context.root.$apollo из первых рук? - person JoeSchr; 05.12.2019
comment
Круто опубликует, его подход к настройке намного лучше! - person Austio; 16.12.2019

Теперь в nuxt-composition-api есть официальный помощник onGlobalSetup

Согласно документации, вы просто используете его в плагине следующим образом:

import { onGlobalSetup } from 'nuxt-composition-api'

export default () => {
  onGlobalSetup(() => {
    provide('globalKey', true)
  })
}
person Pascal Martineau    schedule 15.06.2020
comment
ах, приятно знать. К сожалению, я не могу использовать nuxt-composition-api, он всегда выдает ошибку, когда я наконец создаю nuxt. честно говоря, я использую nuxt-ts, так что, вероятно, он еще не предназначен для машинописного текста ... - person JoeSchr; 17.06.2020
comment
Я перестал использовать nuxt-ts, так как это не рекомендуется для производства и чрезмерного использования памяти, плюс я столкнулся с некоторыми странными проблемами .. - person Pascal Martineau; 18.06.2020
comment
да, это определенно было хлопотно. но лучше, чем не использовать машинописный текст ... Могу я спросить, что еще вы используете сейчас? - person JoeSchr; 18.06.2020
comment
Я все еще использую @nuxt/typescript-build, но не среду выполнения, которая позволяет использовать TS в nuxt.config. - person Pascal Martineau; 19.06.2020
comment
ах, попался. Я должен это изучить. Вам приходилось изменять файл webpack, чтобы nuxt работал с компонентами в ts? есть ли шанс, что у вас есть ссылка? Спасибо! - person JoeSchr; 19.06.2020
comment
Настройка Nuxt TypeScript работает OOTB, просто не настраивайте runtime и оставьте nuxt.config.js, поскольку JS и компоненты должны нормально работать в TS. - person Pascal Martineau; 19.06.2020
comment
Спасибо, кажется, мне стоило уделить больше внимания optional при его настройке! Я попробую, но перед этим мне придется перенести свои modules и serverMiddleware на JS. - person JoeSchr; 21.06.2020