@nuxtjs/composition-apiと@nuxt/contentを使ってみる

# @nuxtjs/composition-api / @nuxt/content とは

Nuxt v2.13(2020-06-19)辺りから使えるレベルになってきている様子
![nuxt2.13.0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52777/7f59b5e1-e5b0-539d-5e47-0d06931f7190.png)

専用のページもある

* https://content.nuxtjs.org/ja/
* https://composition-api.nuxtjs.org/

## @nuxtjs/composition-api の概要
* Vue 3 のComposition APIをNuxtの仕様に合わせたもの

## @nuxt/content の概要
* MarkdownやJSONなどのファイルからAPIのようにfetchできるようにするもの

# create-nuxt-app を使用してnuxtアプリを生成
https://github.com/nuxt/create-nuxt-app
1.Package manager: Yarn
2.Programming language: TypeScript
3.UI framework: Vuetify
4.Nuxt.js modules: Axios / PWA / Content
5.Linting tools: ESLint / Prettier / Lint staged files / StyleLint
6.Testing framework: Jest
7.Rendering mode: Universal(SSR / Static)
8.Deployment target: Server
9.Deployment tools: none

@nuxt/contentはmodulesへ記載される

@nuxtjs/composition-apiをインストールする
https://composition-api.nuxtjs.org/setup

追記する

```nuxt.config.ts
buildModules: [
  // https://github.com/nuxt-community/composition-api
  '@nuxtjs/composition-api',
],
```

試したリポジトリ
https://github.com/seiy4/nuxt214/tree/master/src

![directry-structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52777/d414aa76-2d61-37c2-73a9-81a8c39a69a1.png)


# @nuxtjs/composition-api
https://www.npmjs.com/package/@nuxtjs/composition-api
https://github.com/nuxt-community/composition-api/blob/main/src/entrypoint.ts
 ![nuxt-entrypoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52777/4c1d3290-3de5-a556-9958-5001382c7d1e.png)



componentを定義

```components/TheUser.vue
<template>
  <div>Name: {{ fullName }}, Message: {{ message }}</div>
</template>

<script lang="ts">
import { defineComponent, computed, ref } from '@nuxtjs/composition-api'

interface User {
  firstName: string
  lastName: string
}

export default defineComponent({
  props: {
    user: {
      type: Object as () => User,
      required: true,
    },
  },

  setup({ user }) {
    const fullName = computed(() => `${user.firstName} ${user.lastName}`)
    const message = ref('This is a message')

    return {
      fullName,
      message,
    }
  },
})
</script>
```

```components/TheCounter.vue
<template>
  <div>
    <v-btn @click="decrement">-</v-btn>
    <span>{{ count }}</span>
    <v-btn @click="increment">+</v-btn>
  </div>
</template>

<script lang="ts">
import { reactive, computed } from '@nuxtjs/composition-api'

export default {
  setup() {
    const state = reactive({
      count: 0,
    })
    const count = computed(() => state.count)

    return {
      count,
      increment() {
        state.count++
      },
      decrement() {
        state.count--
      },
    }
  },
}
</script>
```

実際に使うとき

```main.vue
<template>
  <div>
    <the-counter />
    <the-user :user="user" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        firstName: 'Taro',
        lastName: 'Yamada',
      },
    }
  },
}
</script>
```


# @nuxt/content

https://content.nuxtjs.org/ja/writing
`content` ディレクトリへMarkdownを追加する

## Code

```hello.vue
<template>
  <div>
    <h3>{{ page.title }}</h3>
    <nuxt-content :document="page" />
  </div>
</template>

<script>
export default {
  async asyncData({ $content }) {
    const page = await $content('hello').fetch()

    return {
      page,
    }
  },
</script>
```

## markdown sample
![markdown-sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52777/6d34bc49-c413-d504-2275-dd4e8d1bc7ee.png)

## output
![nuxt:content-output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52777/dc573e67-2e7a-1da6-2735-9c5989fcc100.png)