如何从组件的方法访问注入的存储库

How to access a injected repository from a component's method

假设我们在 plugin/service-container.js

上注入了这个存储库
import nodeFetch from 'node-fetch'
import { AbortController as NodeAbortController } from 'node-abort-controller'

import HttpClient from '@/services/httpClient'
import PostRepository from '@/repositories/posts'


export default ({ app }, inject) => {
  if (!process.client || app.context.env.NUXTJS_DEPLOY_TARGET === 'server') {
    inject('postRepository', postRepository)
  }
}

我总是从 asyncData 方法加入 API 存储库,如下所示:

export default {
  async asyncData ({ $postRepository,  }) {
    const posts = await $postRepository.getAllPaginated(page, 11)
    return {
      posts,
    }
  }
}

但我需要在一个方法中访问它,这确实有效但是:

Async method 'asyncData' has no 'await' expression.eslintrequire-await

正确的方法是什么?我无法在线找到它(我发现的唯一示例涉及使用商店)

export default {
  async asyncData ({ $postRepository }) {
    this.$postRepository = $postRepository 
  },
  methods: {
    async loadMore () {
      if (this.page < this.posts.numPages) {
        const posts = await this.$postRepository.getAllPaginated(this.page + 1, 11)
      }
    }
  }
}

错误来自这里

async asyncData ({ $postRepository }) {
  this.$postRepository = [missing await here] $postRepository 
},

来自the documentation

This hook can only be used for page-level components. Unlike fetch, asyncData cannot access the component instance (this). Instead, it receives the context as its argument. You can use it to fetch some data and Nuxt will automatically shallow merge the returned object with the component data.

因此,您不能在 asyncData 中使用任何类型的 this.loadMore,因为它还没有访问该实例的权限。所以,inject确实是正确的做法。

有了这样的插件

export default ({ _ }, inject) => {
  inject('customTest', async () => {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    return await response.json()
  })
}

还有这样的页面

<template>
  <div>
    <pre>item: {{ item }}</pre>
  </div>
</template>

<script>
export default {
  async asyncData({ $customTest }) {
    const item = await $customTest()
    return { item }
  },
}
</script>

它没有调用方法,但您完全可以使用 this.$nuxt.refresh() 再次获取它并在商店更新后增加存储库调用的索引。
可以像

这样引用
await fetch(`https://jsonplaceholder.typicode.com/todos/${indexFromVuex}`)

你当然也可以把它放在本地

<template>
  <div>
    <pre>item: {{ item }}</pre>

    <button @click="fetchNewItem">fetch new item</button>
  </div>
</template>

<script>
export default {
  async asyncData({ $customTest }) {
    const item = await $customTest()
    return { item }
  },
  data() {
    return {
      index: 1,
    }
  },
  methods: {
    async fetchNewItem() {
      this.index += 1
      this.item = await this.$customTest(this.index)
    },
  },
}
</script>

所以是的,我认为 asyncData 没有其他可能的方法。
fetch() 钩子更灵活一些,但它的工作方式也完全不同。
无论如何,使用这两种方法,您完全可以解决 HTTP 调用的问题。

似乎可以在任何方法中使用简单的 this.$postRepository 访问(在这种情况下)注入的依赖项,所以我什至不需要那个 asyncData