Nuxt

Integrate Strapi with Nuxt 3.

Nuxt 3 入门

本集成指南遵循 快速入门指南,并假设您已完全完成“动手”路径。您应该能够通过浏览 URL http://localhost:1337/api/restaurants 来使用该 API。

如果您尚未阅读快速入门指南,则使用 Nuxt 3 请求 Strapi API 的方式保持不变,只是您不会获取相同的内容。

创建 Nuxt 3 应用

使用 npx 包运行器创建基本的 Nuxt 3 应用

bash
npx nuxi init nuxt-app

使用 HTTP 客户端

对于此示例,我们使用了超棒的 @nuxt/strapi 模块和 Nuxt 辅助函数 $fetch(基于 ohmyfetch)。您可以选择其中任何一种变体。

bash
@nuxtjs/strapi
bash
yarn add --dev @nuxtjs/strapi

GET 请求 - 获取实体列表或一个实体

restaurant 集合类型执行 GET 请求以获取您的餐厅。

确保您已为 restaurant 集合类型激活 findfindOne 权限。

@nuxtjs/strapi 公开 Nuxt 3 自动导入的可组合项。请注意,必须重命名 delete 函数,因为它是 JavaScript 中的保留字。

使用 @nuxtjs/strapi 的示例 GET 请求

vue
@nuxtjs/strapi
vue
<script setup lang="ts">
import type { Restaurant } from '~/types'
const { find, findOne, create, update, delete: remove } = useStrapi()

// Get all restaurants
const response = await find<Restaurant>('restaurants')

// Get one restaurant by id
const response = await findOne<Restaurant>('restaurants', restaurantId)
</script>
Example response
json
// List of the restaurants
{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "Biscotte Restaurant",
        "description": "欢迎来到 Biscotte 餐厅!\nBiscotte 餐厅提供以新鲜、优质食材为基础的美食,通常采用当地食材,尽可能采用有机食材,并且始终由充满热情的生产商制作。",
        "createdAt": "2022-10-29T09:37:55.061Z",
        "updatedAt": "2022-11-07T18:53:27.702Z",
        "publishedAt": "2022-10-29T09:47:48.782Z"
      }
    },
    {
      "id": 2,
      "attributes": {
        "name": "Dolemon Sushi",
        "description": "不容错过的日本寿司店。奶酪和鲑鱼卷非常美味。",
        "createdAt": "2022-10-29T09:37:55.061Z",
        "updatedAt": "2022-11-07T18:53:27.702Z",
        "publishedAt": "2022-10-29T09:47:48.782Z"
      }
    }
  ],
  "meta": {
    "pagination": { "page": 1, "pageSize": 25, "pageCount": 1, "total": 4 }
  }
}
json
// One restaurant
{
  "data": {
    "id": 1,
    "attributes": {
      "name": "Biscotte Restaurant",
      "description": "Welcome to Biscotte restaurant! \nRestaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.",
      "createdAt": "2022-10-29T09:37:55.061Z",
      "updatedAt": "2022-11-07T18:53:27.702Z",
      "publishedAt": "2022-10-29T09:47:48.782Z"
    }
  },
  "meta": {}
}

POST 请求 - 创建新实体

对“餐厅”集合类型执行“POST”请求以创建餐厅。

确保您已激活“餐厅”集合类型的“创建”权限。

js
@nuxtjs/strapi
js
await create < Restaurant > ('restaurants', {
  name: restaurantName,
  description: restaurantDescription
})

PUT 请求 - 更新现有实体

对“restaurant”集合类型执行“PUT”请求以更新您的餐厅。

确保您已为“restaurant”集合类型激活“put”权限。

@nuxtjs/strapi
js
// 使用 @nuxtjs/strapi 的示例 PUT 请求
await update < Restaurant > ('restaurants', restaurantId, {
  name: restaurantName,
  description: restaurantDescription
})
fetch
js
// 使用 $fetch 的 PUT 请求示例
await $fetch(`http://localhost:1337/api/restaurants/${restaurantId}`, {
  method: 'PUT',
  body: {
    data: {
      name: restaurantName,
      description: restaurantDescription
    }
  }
})

::

DELETE 请求 - 删除现有实体

对“餐厅”集合类型执行“DELETE”请求以删除您的餐厅。

确保您已激活“餐厅”集合类型的“删除”权限。

js
@nuxtjs/strapi
js
// 使用 @nuxtjs/strapi 的 DELETE 请求示例
await remove < Restaurant > ('restaurants', restaurantId)

示例

考虑一个实现上述功能的简单 CRUD Nuxt 应用程序示例。

@nuxtjs/strapi

vue
./pages/index.vue
vue
<script setup lang="ts">
import type { Restaurant } from '~/types'
const { find, delete: remove } = useStrapi() // delete is keyword in JS, must not be used
const { data: restaurants, refresh } = await useAsyncData(
  'restaurants',
  () => find<Restaurant>('restaurants')
)

async function deleteRestaurant(restaurantId: number) {
  await remove<Restaurant>('restaurants', restaurantId)
  refresh()
}
</script>

<template>
  <div>
    <ul>
      <li v-for="restaurant in restaurants?.data" :key="restaurant.id">
        {{ restaurant.attributes.name }}
        <button @click="$router.push(`${$route.path}/restaurant/${restaurant.id}`)">
          Edit
        </button>
        <button @click="deleteRestaurant(restaurant.id)">
          Delete
        </button>
      </li>
    </ul>

    <nuxt-link :to="`${$route.path}/restaurant/create`">
      Create
    </nuxt-link>
  </div>
</template>

fetch

vue
./pages/index.vue
vue
<script setup>
const { data: restaurants, refresh } = await useAsyncData(
  'restaurants',
  () => $fetch('http://localhost:1337/api/restaurants')
)

async function deleteRestaurant(restaurantId) {
  await $fetch(`http://localhost:1337/api/restaurants/${restaurantId}`, {
    method: 'DELETE'
  })
  refresh()
}
</script>

<template>
  <div>
    <ul v-if="loaded">
      <li v-for="restaurant in restaurants.data" :key="restaurant.id">
        {{ restaurant.attributes.name }}
        <button @click="$router.push(`${$route.path}/restaurant/${restaurant.id}`)">
          Edit
        </button>
        <button @click="deleteRestaurant(restaurant.id)">
          Delete
        </button>
      </li>
    </ul>
    <div v-else>
      Loading...
    </div>
    <nuxt-link :to="`${$route.path}/restaurant/create`">
      Create
    </nuxt-link>
  </div>
</template>