検索ページを作成しよう【Vue propsとTypeScriptの書き方 解説】
  • 2022.02.19に公開
  • ブログ構築TS
  • 8. NetlifyFunctionsを使った検索機能
  • No.7 / 9

今回達成すること

  • 検索結果を表示するページファイルと、
  • ページタイトルを表示するコンポーネントファイルを作成します。

2022-02-18 09-31-23

検索ページを作成する

「pages」ディレクトリに、検索結果を表示するsearch.vueを作成します。

% touch pages/search.vue

レイアウトファイルの指定とページタイトルを用意します。

pages/search.vue
<template>
  <v-container>
    <v-card-title
      class="text-h5 font-weight-bold"
    >
      {{ pageTitle }}
    </v-card-title>
  </v-container>
</template>

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

@Component
export default class SearchPage extends Vue {
  layout (): string {
    return 'app'
  }

  pageTitle: string = this.$my.routePageTitle(this.$route.name)
}
</script>

日本語翻訳データを用意する

検索ページのタイトルをja.jsonに用意します。

locales/ja.json
{
  "pages": {
    "privacy": "プライバシーポリシー",
    // 追加
    "search": "サイト内検索"
  }
}

ja.jsonの変更は、ホットリロードでうまく読み込まれません。

Nuxtサーバーを再起動しましょう。

% yarn dev

検索ページを確認しよう

前回作成した検索フォームに適当な文字列を入力し、エンターキーを押しましょう。

そうすると、/searchページに遷移します。

URLにクエリ?q=が付いていることも確認してください。

2022-02-18 09-31-23

無事ページタイトルが日本語化されました。

ページタイトルをコンポーネント化する

ページタイトルのスタイリングはprivacy.vueと全く同じです。

<v-card-title
  class="text-h5 font-weight-bold"
>
  {{ pageTitle }}
</v-card-title>

そこで、このUIをコンポーネント化します。

UIコンポーネントファイルを作成する

「components/Ui」ディレクトリにUiPageTitle.vueを作成しましょう。

% touch components/Ui/UiPageTitle.vue

Vueのpropsを使用し、titlesubTitleを受け取ります。

components/Ui/UiPageTitle.vue
<template>
  <v-card
    flat
    tile
    color="transparent"
  >
    <v-card-title
      class="text-h5 font-weight-bold"
    >
      {{ title }}
    </v-card-title>

    <v-card-text
      v-if="subTitle"
      class="font-weight-bold"
    >
      {{ subTitle }}
    </v-card-text>
  </v-card>
</template>

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

@Component
export default class UiPageTitleComponent extends Vue {
  @Prop({
    type: String,
    required: true
  })
    title!: string

  @Prop({
    type: String,
    default: ''
  })
    subTitle?: string
}
</script>
  • <v-card>
    • flat ... Boxに影をつけない。
    • tile ... 角張ったBoxにする。
    • color="transparent" ... background-colorを透明に。

VueのpropsとTypeScriptの書き方

Vueのpropsnuxt-property-decoratorを使用すると@Prop({ <オプション> })に書き変わります。

必須のバインドキーの書き方

コンポーネント必須のバインドキーは、

  • @Prop => requiredプロパティをtrueに、
  • title! => 変数にはエクスクラメーションマーク(!)を付け、nullundefinedにならないことを宣言します。
props(受け取り側)
@Prop({
  type: String,
  required: true
})
  title!: string

required: trueを宣言すると、コンポーネントにそのバインドキーがない場合にエラーとなります。

v-bind(送信側)
<!-- titleキー必須 -->
<ui-page-title
  :title="hoge"
/>

必須ではないバインドキーの書き方

必須ではないバンドキーは、

  • subTitle? => クエスチョンマークを付けて変数を宣言します。
  • @prop => defaultプロパティは無くても構いません。今回は明示的にtypeと一致させて初期値を代入しています。
props(受け取り側)
@Prop({
  type: String,
  default: ''
})
  subTitle?: string

変数に?を付与しないと、「コンストラクターで確実に代入されません。」というTypeScriptのエラーが出ます。

/*
	TS Error
	Property 'subTitle' has no initializer and is not definitely assigned in the constructor.
*/
@Prop({
  type: String,
  default: ''
})
  subTitle: string

また変数に直接初期値を代入すると、今度はバインドされたデータを受け取ることができず、Vueがエラーを吐きます。

/*
	Vue Error
	Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. 
	Instead, use a data or computed property based on the prop's value. Prop being mutated: "subTitle"
*/
@Prop({
  type: String
})
  subTitle: string = ''

propsの書き方には気をつけてください。

ページタイトルコンポーネントに書き換える

  • search.vue
  • privacy.vue

上記2つのページファイルのタイトルを<ui-page-title>コンポーネントに書き換えます。

pages/search.vue
<template>
  <v-container>
    <ui-page-title
      :title="pageTitle"
    />
  </v-container>
</template>

プライバシーポリシーページはサブタイトルを変数で用意します。

pages/privacy.vue
<template>
  <v-container>
    <!-- 追加 -->
    <ui-page-title
      :title="pageTitle"
      :sub-title="pageSubTitle"
    />

    <!-- 削除 -->
    <!-- <v-card
      flat
      color="transparent"
    >
      <v-card-title
        class="text-h5 font-weight-bold"
      >
        {{ pageTitle }}
      </v-card-title>

      <v-card-text
        class="font-weight-bold"
      >
        {{ $config.appName }}(以下、当サイト)では、個人情報の保護およびその適切な取り扱いについて、以下のとおりプライバシーポリシー(以下、本ポリシー)を定めております。
      </v-card-text>
    </v-card> -->
    ...
</template>

<script lang="ts">
...
@Component
export default class PrivacyPage extends Vue {
  ...
  pageTitle: string = this.$my.routePageTitle(this.$route.name)
  // 追加
  pageSubTitle: string = `${this.$config.appName}(以下、当サイト)では、個人情報の保護およびその適切な取り扱いについて、以下のとおりプライバシーポリシー(以下、本ポリシー)を定めております。`
}
</script>

それぞれのページにアクセスして表示が正しいか確認してください。

今回の作業は以上です。

% git add -A
% git commit -m "Add search page and page title component"

まとめと次回

今回は検索ページとその中で使用するページタイトルコンポーネントを作成しました。

次回はContentfulにAPIリクエストを行うFunctionsプロジェクトを作成し、検索機能を完成させます。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる。そんな方に向けた単発・短期間メンターサービスを行っています。
独学プログラマのサービス
ブログ構築TSの投稿
1
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #01
Nuxt.jsをローカルPCに立ち上げよう
2
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #02
Nuxt.jsプロジェクトをGitHubにPushしよう
3
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #03
nuxt-property-decoratorのインストールとTypeScriptのセットアップ
1
  • Vuetifyセットアップ
  • /
  • #01
TypeScript環境のNuxt.jsにVuetifyを導入しよう
2
  • Vuetifyセットアップ
  • /
  • #02
VuetifyにカスタムCSSを追加してSASS変数を理解しよう
3
  • Vuetifyセットアップ
  • /
  • #03
VuetifyにカスタムSVGアイコンを追加しよう
1
  • NetlifyCLIを使ったNuxtデプロイ
  • /
  • #01
Netlify CLIをインストールして本番環境のサイトを作成しよう
2
  • NetlifyCLIを使ったNuxtデプロイ
  • /
  • #02
netlify.tomlを使ってNuxt.jsをNetlifyに手動デプロイしよう
1
  • Contentfulモデル構築
  • /
  • #01
Contentfulの料金とCommunityプランの無料枠を理解する
2
  • Contentfulモデル構築
  • /
  • #02
Contentfulへ新規会員登録、ロケールの変更、API Keyの発行を行う
3
  • Contentfulモデル構築
  • /
  • #03
Contentful ブログカテゴリーモデルを作成しよう
4
  • Contentfulモデル構築
  • /
  • #04
Contentful カテゴリーモデルに1対1で関連づくblogPostモデルを作成しよう
5
  • Contentfulモデル構築
  • /
  • #05
Contentful ブログ記事に1対多で関連づくplogTagモデルを作成しよう
6
  • Contentfulモデル構築
  • /
  • #06
Contentful カテゴリー・ブログ記事・タグコンテンツを作成しよう
1
  • Nuxt.js×Contentfulセットアップ
  • /
  • #01
Nuxt.js×Contentfulセットアップ。モジュールのインストールからAPI Keyの登録まで
2
  • Nuxt.js×Contentfulセットアップ
  • /
  • #02
Contentful APIリクエストの実行 Nuxt.jsにブログコンテンツを表示しよう
3
  • Nuxt.js×Contentfulセットアップ
  • /
  • #03
ContentfulAPIをNetlifyにデプロイしよう【Nuxt FullStaticのasyncDataとfetch】
1
  • Vuex×TypeScriptセットアップ
  • /
  • #01
Vuexの型付け vuex-module-decoratorsとnuxt-typed-vuexどちらを使用するか
2
  • Vuex×TypeScriptセットアップ
  • /
  • #02
nuxt-typed-vuexのインストールとセットアップ。Vuexの型定義と呼び出し方
3
  • Vuex×TypeScriptセットアップ
  • /
  • #03
VuexにContentfulの型定義ファイルとnuxtServerInitを追加しよう
4
  • Vuex×TypeScriptセットアップ
  • /
  • #04
VuexにContentfulAPIレスポンスを保存してVueファイルに表示しよう
1
  • コンテンツページ構築
  • /
  • #01
ブログアプリのページ設計とNuxt.jsの動的ルーティングについて理解しよう
2
  • コンテンツページ構築
  • /
  • #02
カテゴリーのコンテンツページを作成しよう【Nuxt.js×Contentful】
3
  • コンテンツページ構築
  • /
  • #03
カテゴリーに関連付くブログ記事一覧を表示しよう【Nuxt.js×Contentful】
4
  • コンテンツページ構築
  • /
  • #04
injectを使用して共通エラー処理メソッドを作成しよう【Nuxt×TypeScript】
5
  • コンテンツページ構築
  • /
  • #05
NuxtChildを使用してブログ記事ページを作成しよう【Nuxt.js×TypeScript】
6
  • コンテンツページ構築
  • /
  • #06
タグ一覧ページとタグ関連づく記事一覧を表示しよう【Nuxt.js×TypeScript】
7
  • コンテンツページ構築
  • /
  • #07
プライバシーポリシーページを作成しよう【Nuxt.js×TypeScript】
8
  • コンテンツページ構築
  • /
  • #08
@nuxtjs/i18nのインストールとセットアップ。ページタイトルの翻訳化【TypeScript】
1
  • NetlifyFunctionsを使った検索機能
  • /
  • #01
Netlify Functionsを使ってクエリを返す関数を作成しよう【Nuxt.js×TypeScript】
2
  • NetlifyFunctionsを使った検索機能
  • /
  • #02
Netlify Functionsプロジェクトをデプロイしよう【Nuxt.js×TypeScript】
3
  • NetlifyFunctionsを使った検索機能
  • /
  • #03
Nuxt.js × axiosセットアップ Netlify Functionsにリクエストを行う準備をしよう
4
  • NetlifyFunctionsを使った検索機能
  • /
  • #04
オリジン•CORS•プリフライトリクエストを理解する【Nuxt.js×Netlify Functions】
5
  • NetlifyFunctionsを使った検索機能
  • /
  • #05
Netlify Functionsを使ってフォームバリデーション機能を構築しよう【Nuxt.js】
6
  • NetlifyFunctionsを使った検索機能
  • /
  • #06
ツールバーに表示する検索フォームを作成しよう【Nuxt.js×TypeScript】
7
  • NetlifyFunctionsを使った検索機能
  • /
  • #07
検索ページを作成しよう【Vue propsとTypeScriptの書き方 解説】
8
  • NetlifyFunctionsを使った検索機能
  • /
  • #08
Netlify FunctionsからContentfulAPIリクエストを送ろう【Nuxt.js】
9
  • NetlifyFunctionsを使った検索機能
  • /
  • #09
検索ページに「もっと見る」ボタンを実装しよう【Nuxt.js×TypeScript】
1
  • ブログMarkdown対応
  • /
  • #01
@nuxtjs/markdownitのインストールとセットアップ【Nuxt.js×TypeScript】
2
  • ブログMarkdown対応
  • /
  • #02
Nuxt.js×markdown-it 外部リンクを別タブで開くプラグインを追加しよう
3
  • ブログMarkdown対応
  • /
  • #03
Nuxt.js×markdown-it 内部リンクをVueRouterで高速にページ遷移しよう
4
  • ブログMarkdown対応
  • /
  • #04
Nuxt.js×markdown-it アンカーリンクとブログ目次を自動生成しよう
独学プログラマ
独学でも、ここまでできるってよ。
CONTACT
Nuxt.js制作のご依頼は下記メールアドレスまでお送りください。