【问题标题】:How to provide/inject into Vue root instance WITH nuxt and @vue/composition-api?如何使用 nuxt 和 @vue/composition-api 提供/注入 Vue 根实例?
【发布时间】:2020-03-30 13:18:35
【问题描述】:

我正在尝试将@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 正在使用composition-api::provide() 创建它自己的属性_provided

如果我使用 nuxt 插件的 inject$ 连接。如果我通过ctx.app._provided = 直接写一个_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 };
  },
});

但是在InstallGraphQl::setup之前调用了导出组件的setup...

编辑:有关@vue/apollo-composable 的更多信息,请参见此处的讨论:https://github.com/vuejs/vue-apollo/issues/687

【问题讨论】:

    标签: typescript nuxt.js vue-apollo vuejs3 vue-composition-api


    【解决方案1】:

    现在在nuxt-composition-api 中有一个官方的onGlobalSetup 助手

    根据文档,您只需像这样在插件中使用它:

    import { onGlobalSetup } from 'nuxt-composition-api'
    
    export default () => {
      onGlobalSetup(() => {
        provide('globalKey', true)
      })
    }
    

    【讨论】:

    • 啊,很高兴知道。遗憾的是我不能使用nuxt-composition-api,当我最终构建nuxt 时它总是会抛出一个错误。公平地说,我使用的是nuxt-ts,所以它可能还不是为打字稿制作的......
    • 我停止使用nuxt-ts,因为它不推荐用于生产和膨胀内存使用,另外我遇到了一些奇怪的问题..
    • 是的,这绝对是一件麻烦事。但总比不使用打字稿好……请问您现在还使用什么?
    • 我仍然使用@nuxt/typescript-build,但不是允许在 nuxt.config 中使用 TS 的运行时。
    • Nuxt TypeScript setup 可以在 OOTB 中工作,只是不要配置 runtime 并保留 nuxt.config.js,因为 JS 和组件应该可以在 TS 中正常工作。
    【解决方案2】:

    只需将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 不太熟悉,但我认为代码应该可以正常工作。

    【讨论】:

    • 虽然@Austio 给我带来了正确的方向,但在我的default.vue::setup() 中调用provide() 触发了内存不足错误。 (我认为是因为它不断重新加载,因为我还在我的default.vue 中查询loggedInUser)而且我还认为将provide(DefaultApolloClient,..) 放在它自己的文件中而不是default.vue 中是更正确的方法。
    【解决方案3】:

    我不使用 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'
      ],
    

    【讨论】:

    • 感谢您的回答,这似乎是目前唯一可行的方法?但是如何配置 apollo?因为虽然我得到了一个默认的 apolloClient,但它仍然是空的,而不是填充了我来自 nuxt.config.ts 的设置。你是在第一手使用“@nuxt/vue-apollo”创建context.root.$apollo吗?
    • 真棒会发帖,他的设置方法要好得多!
    猜你喜欢
    • 2021-06-22
    • 2020-04-09
    • 1970-01-01
    • 2021-07-17
    • 2021-08-28
    • 2020-11-16
    • 2021-10-13
    • 2020-08-26
    • 2021-02-06
    相关资源
    最近更新 更多