SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

TypeScriptで学ぶJavaScriptフレームワーク「Vue.js」の利用法

TypeScriptとも相性抜群なライブラリ──Vue.jsで状態管理を行う新定番「Pinia」を解説!

TypeScriptで学ぶJavaScriptフレームワーク「Vue.js」の利用法 第8回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Piniaのステート、ゲッター、アクションを使いこなす

 以下では、Piniaのステート、ゲッター、アクションに関わる機能を説明していきます。説明のために、スマートフォン機種の名前(name)、会社(vendor)、価格(price)、機能リスト(features)のステートと、価格をカンマ区切りして返却するゲッター(formattedPrice)を含む、リスト9のストアを利用します。

[リスト9]スマートフォン情報を管理するストア(p004-mutate-state/src/stores/phone.ts)
export const usePhoneStore = defineStore('phone', () => {
  // ステート
  const name = ref('iPhone 15 Pro')
  const vendor = ref('Apple')
  const price = ref(159800)
  const features = ref(['5G', 'チタニウム', 'アクションボタン'])
  // ゲッター
  const formattedPrice = computed(() => {
    const formatter = new Intl.NumberFormat('ja-JP')
    return formatter.format(price.value)
  })
  // 返却
  return { name, vendor, price, features, formattedPrice }
})

ステートの参照と更新

 ストアのステートを参照・更新する方法について、図4のサンプルで説明します。このサンプルでは、機種、会社、価格のテキストボックスの内容を変更すると画面に反映されます。また、機能を追加・削除することもできます。

図4 ステートを参照・更新するサンプル(p004-mutate-state)
図4 ステートを参照・更新するサンプル(p004-mutate-state)

 まず機種、会社、価格のテキストボックスを含むMutateStateコンポーネントの<template>部は、リスト10の通りです。ストアのステート(name、vendor、price)は、v-modelディレクティブに直接指定できます。この指定により、入力内容とステートが双方向データバインディングで同期します。なお、(1)の「v-model.number」は、store.priceがnumber型である指定です。

[リスト10]ステートをテキストボックスに紐づける指定(p004-mutate-state/src/components/MutateState.vue)
<div>機種:<input v-model="store.name"></div>
<div>会社:<input v-model="store.vendor"></div>
<div>価格:<input v-model.number="store.price"></div> <!--(1)-->

 双方向データバインディングではなく、ストアオブジェクトのプロパティとしてステートを直接参照・更新することもできます。機能を追加・削除するMutateFeaturesコンポーネント(リスト11)を例に説明します。ここではstore.featuresプロパティ(配列)に対して、pushメソッドで機能(テキストボックスの入力値であるinputFeature)を配列の最終要素に追加し、popメソッドで配列の最終要素を削除します。store.featuresプロパティが更新されると、その内容が画面表示に反映されます。なおここでは、各処理後にテキストボックスの入力値(inputFeature)を空にしています。

[リスト11]配列形式のステートを更新する処理(p004-mutate-state/src/components/MutateFeatures.vue)
// 追加ボタンの処理
function onClickButtonAddFeature() {
  store.features.push(inputFeature.value)
  inputFeature.value = ''
}
// 削除ボタンの処理
function onClickButtonDelFeature() {
  store.features.pop()
  inputFeature.value = ''
}

 このようにPiniaのステートは、コンポーネントのデータと同じ方法で参照・更新できます。特別な記述方法は必要ありません。

引数付きゲッター

 ここまで紹介したゲッターは、あたかも変数のように参照していましたが、引数を伴うメソッドの形式でゲッターを提供することもできます。この方法を、図4と同一内容を表示するサンプル(p005-getter-with-param)で説明します。このサンプルでは、リスト9のformattedPriceゲッターをもとに、単位を指定できるformattedPriceWithUnitゲッターを、リスト12の通り実装します。computed関数の引数に設定する関数で、ゲッターの値そのものではなく、値を返す関数を返すように実装します。

[リスト12]引数付きゲッターの実装(p005-getter-with-param/src/stores/phone.ts)
const formattedPriceWithUnit = computed(() => {
  return (unit:string) => `${unit}${formattedPrice.value}`
})

 formattedPriceWithUnitゲッターは、<template>部でリスト13の通り参照できます。

[リスト13]引数付きゲッターの参照(p005-getter-with-param/src/components/ShowStore.vue)
{{ store.formattedPriceWithUnit('¥') }}

非同期アクション

 アクションには非同期処理を含めることができます。この実装を、図5のサンプルで説明します。ボタンを押すと、phone.jsonをネットワーク経由で取得して、その内容でステートを更新します。

図5 非同期アクションのサンプル(p006-async-action)
図5 非同期アクションのサンプル(p006-async-action)

 ボタンクリック時に実行されるfetchDataAsyncアクションは、ストアにリスト14の通り実装します。(1)で、fetch関数を実行してphone.jsonを取得し、それをres.jsonメソッドでJavaScriptオブジェクトに変換します。取得したJavaScriptオブジェクトに含まれる値を利用して、(2)でステートを更新します。

[リスト14]非同期アクションの実装(p006-async-action/src/stores/phone.ts)
async function fetchDataAsync() {
  // phone.jsonを取得 ...(1)
  var result = await fetch('/phone.json').then(res => res.json())
  // ステートを更新 ...(2)
  name.value = result.name
  vendor.value = result.vendor
  price.value = result.price
  features.value = result.features
}

 なお、取得するphone.jsonは、リスト15の内容をpublicフォルダーに配置します。

[リスト15]fetchで取得するデータ(p006-async-action/public/phone.json)
{
  "name": "Pixel 8 Pro",
  "vendor": "Google",
  "price": 159900,
  "features": ["おサイフケータイ", "5G", "温度計"]
}

まとめ

 本記事では、Vue.jsの状態管理ライブラリーPiniaを、Vuexと比較しながら説明しました。Vuexで実現していた状態管理を、よりシンプルかつ自然な形式で実装できるようになり、TypeScriptとの親和性もより高くなりました。

 本連載では、Vue.jsをTypeScriptで活用するためのさまざまな技術要素を説明してきました。ViteベースのCLIツールを利用することで、今回紹介したPiniaなどライブラリーを含めて、追加設定を行うことなくTypeScriptを利用できます。Vue.jsのWebページを作成する際、CLIツールでTypeScriptを有効にしてみてはいかがでしょうか。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
TypeScriptで学ぶJavaScriptフレームワーク「Vue.js」の利用法連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18727 2023/12/11 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング