LoginSignup
3
0

More than 3 years have passed since last update.

Contentfulで投稿ごとにnuxtのcomponentを切り替える方法(動的コンポーネントの実装)

Last updated at Posted at 2019-12-19

はじめに

JAMstackにハマってnuxt, contentful, netlifyでブログなどを作っていて
contentfulの投稿ごとにnuxtで使うcomponentを切り替えたいと思うことが何度かあって、その方法を実装したのでそれについて共有できればと思いました。
nuxtの導入や、contentfulとの連携などについては、あとあと書くかもしれませんし、すでに他の方がわかりやすい記事を書かれているのでそちらを参考にしてください。
また、例として載せているコードはTypeScriptで書いています。

Contentful

Model設定

まず、Content modelにフィールドを追加します。
Add new field > Text
スクリーンショット 2019-12-19 9.39.09.png

Nameはここではtemplate、Short text, exact searchにチェック。
Create and cofigureをクリック
スクリーンショット 2019-12-19 9.39.24.png

Validations タブに移動し、Accept only specified valuesにチェック。
スクリーンショット 2019-12-19 9.43.43.png

表示されるテキストボックスに任意のtemplate名を入力してEnter。
これを切り替えたいtemplate名として使用していきます。
スクリーンショット 2019-12-19 9.52.41.png

Appearanceタブに移動し、Dropdownを選択。
Saveをクリック。
スクリーンショット 2019-12-19 9.48.26.png

これで、Content Modelの設定は終わりです。

Contentの設定

Modelでtemplateのフィールドを追加したので、記事投稿画面にtemplateというドロップダウンのフォームが追加されています。
ここで好きなtemplate名を選んで保存します。
スクリーンショット 2019-12-19 9.53.43.png

nuxt

いよいよnuxtでcomponentの切り替えを実装します。
まずpagesは以下のようにしています。

├── pages
│   ├── index.vue
│   └── post
│       └── _slug.vue

Vue.jsの公式で動的なコンポーネント、として説明があります。
実際のコードは以下のようにします。

/pages/post/_slug.vue
<template lang="pug">
div
  template-wrapper
    component(:is="checkTemplate")
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

import TemplateWrapper from '~/components/template/TemplateWrapper.vue'
import TemplateOne from '~/components/template/TemplateOne.vue'
import TemplateTwo from '~/components/template/TemplateTwo.vue'

@Component({
  components: {
    TemplateWrapper,
    TemplateOne,
    TemplateTwo
  }
})
export default class Slug extends Vue {
  get currentPost() {
    return this.$store.state.post.currentPost
  }
  get checkTemplate() {
    const template = this.currentPost.fields.template
    if (template === 'template1') {
      return templateOne
    } else if (template === 'Template2') {
      return TemplateTwo
    }
  }
}
</script>

<style scoped lang="scss"></style>

TemplateWrapper.vue
<template lang="pug">
  div
    slot
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

@Component({})
export default class TemplateWrapper extends Vue {}
</script>

<style scoped lang="scss"></style>
TemplateOne.vue
<template lang="pug">
  #template1
    | テンプレート1      
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

@Component()
export default class TemplateOne extends Vue {}
</script>

<style scoped lang="scss"></style>

TemplateTwo.vue
<template lang="pug">
  #template1
    | テンプレート2 
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

@Component()
export default class TemplateTwo extends Vue {}
</script>

<style scoped lang="scss"></style>

コードの解説

_slug.vue で、TemplateWrapper.vueをよびだし、Contentfulのフィールドから記事に設定したtemplateをcheckTemplate()で判定して返します。
TemplateWrapper.vueは、ほとんどなにもしません、slotにTemplateOne,Twoが挿入されます。
TemplateOne,Twoに切り替えて使いたい内容を実装していきます。

おわり

これを実装すると、WordPressの投稿テンプレート的な使い方ができるようになるので、JAMstackをもっと推せるようになるんじゃないかと思います。
動的コンポーネントについての記事は結構あったのですが、contentfulを記事ごとに切り替える方法が見つからなかったので、今回書くことにしました。
もし、こういう方法よりも、もっと簡単に実現する方法があれば教えていただきたいです。
それでは。

参考サイト

Nuxt.jsで動的コンポーネントを使って簡単に切り替え可能なモーダルを実装する

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0