Technical Blog テクニカルブログ
  1. HOME
  2. テクニカルブログ
  3. 【CES出展】Ionicでつくるボタン表示

【CES出展】Ionicでつくるボタン表示

投稿者:関

はじめまして。CESプロジェクトチーム、開発チームの関です。
現在3年目のエンジニアで、普段はチャットボット開発のプロジェクトに参画しています。
このCESプロジェクトでは開発チームの一員としてアプリ開発に携わっております。

CES出展まで、いよいよあと2週間余りとなりました。先日、社内プレゼンやアプリのお披露目会も無事に終わり、 本番に向けてアプリ開発も仕上げに入っております。
前回の記事では、【CES出展】我々が開発してる博物館・美術館向けの新規アプリについての内容でした。     今回は、Ionic初心者が開発で苦労した話とボタンの実装方法についてご紹介します。

同じく初めてIonicを使う方や、Ionicの開発で同じお悩みに直面している方の参考になれば幸いです。


開発で苦労した点

私の場合、IonicやVue.jsを使ったアプリ開発が初めてであったため、単純なボタンの表示や動きといった初歩的な内容にも躓きました。主に美術館、博物館のコースを検索をする画面では、「複数選択ボタン」と「単一選択ボタン」を表示する必要があり、それぞれの仕組みや実装方法について悩みました。下記の記事では、実際のアプリのプログラムを参考にVue.jsとIonicを使ったボタンの実装方法について紹介します。

また、アプリ開発では知識不足を補うために生成AIのNICMA※を活用しました。※NICMAは弊社が開発したGPT活用の生成AIクライアントです。
NICMAの詳細はこちらをご覧ください。


Vue.jsとIonicを使ったボタンの実装方法

下記の画像のように、簡単なボタン表示の実装方法について説明します。

はじめに、JavaScriptを使ってフロントエンドのVue.jsアプリケーションを作成するために必要なモジュールをインポートします。

import { ref } from 'vue';

1.複数選択ボタン

ステップ1: データの定義
複数選択ボタンでは、ボタンを同時に選択状態にするため選択状態を「配列」で管理します。選択状態を管理するためのデータを定義します。
※下記は、美術館の芸術分野をボタンで複数選択することを想定したサンプルプログラムです。

const displays = ref([
  "日本画",
  "西洋画",
  "写真",
  "版画",
  "彫刻",
  "現代美術",
]);

const selectedDisplays = ref<string[]>(["日本画"]);

ステップ2: ボタンの生成と状態の切り替え
次にボタンを生成し、クリックで選択状態を切り替えます。

<template>
  <div>
    <ion-button
      v-for="display in displays"
      :key="display"
      :fill="selectedDisplays.includes(display) ? 'solid' : 'outline'"
      @click="toggleDisplaySelection(display)"
    >
      {{ display }}
    </ion-button>
  </div>
</template>

<script setup lang="ts">
const toggleDisplaySelection = (display: string) => {
  if (selectedDisplays.value.includes(display)) {
    selectedDisplays.value = selectedDisplays.value.filter(d => d !== display);
  } else {
    selectedDisplays.value.push(display);
  }
};
</script>

2. 単一選択ボタン

単一選択ボタンでは、一度に一つのボタンだけが選択状態になるため、選択状態を「単一の変数」で管理します。

ステップ1: データの定義
選択状態を管理するためのデータを定義します。

const recommendations = ref(["含める", "除外する"]);
const selectedRecommend = ref("含める"); 

ステップ2: ボタンの生成と状態の切り替え
ボタンを生成し、クリックで選択状態を切り替えます。

<template>
  <div>
    <ion-button
      v-for="recommend in recommendations"
      :key="recommend"
      :fill="selectedRecommend === recommend ? 'solid' : 'outline'"
      @click="changeRecommend(recommend)"
    >
      {{ recommend }}
    </ion-button>
  </div>
</template>

<script setup lang="ts">
const changeRecommend = (recommend: string) => {
  selectedRecommend.value = recommend;
};
</script>

3.ボタンの色変え(選択時、非選択時)

ボタンの色を選択時と非選択時で変更する方法を説明します。

色変えの実装
IonicのカスタムCSSプロパティを使用して、選択時と非選択時のスタイルを動的に変更します。

<style scoped>
ion-button::part(native) {
  --border-radius: 20px;
  --padding: 10px;
}

ion-button[fill="solid"]::part(native) {
  --background: skyblue; /* 選択状態の背景色(単一選択と複数選択の両方で使える) */
  --color: white;    /* 選択状態の文字色 */
}

ion-button[fill="outline"]::part(native) {
  --background: white; /* 非選択状態の背景色 */
  --color: skyblue;       /* 非選択状態の文字色 */
  --border-color: skyblue; /* 非選択状態のボーダー色 */
}
</style>

4.まとめ

1.複数選択ボタンでは、選択状態を配列として管理し、選択されているかどうかを判定してfill属性を動的に変更します。

2.単一選択ボタンでは、選択状態を単一の変数で管理し、その変数とボタンの値が一致するかどうかを判定してfill属性を動的に変更します。

3.ボタンの色変えは、選択時と非選択時のスタイルをfill属性に基づいて変更し、単一選択ボタンと複数選択ボタンの両方に適用できます。

プログラム

最後に、完成形のプログラムは下記となります。

<template>
  <div>
    <ion-button
      v-for="display in displays"
      :key="display"
      :fill="selectedDisplays.includes(display) ? 'solid' : 'outline'"
      @click="toggleDisplaySelection(display)"
    >
      {{ display }}
    </ion-button>
  </div>
  <div>
    <ion-button
      v-for="recommend in recommendations"
      :key="recommend"
      :fill="selectedRecommend === recommend ? 'solid' : 'outline'"
      @click="changeRecommend(recommend)"
    >
      {{ recommend }}
    </ion-button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const displays = ref([
  "日本画",
  "西洋画",
  "写真",
  "版画",
  "彫刻",
  "現代美術",
]);

const selectedDisplays = ref<string[]>(["日本画"]);
const recommendations = ref(["含める", "除外する"]);
const selectedRecommend = ref("含める"); 

const toggleDisplaySelection = (display: string) => {
  if (selectedDisplays.value.includes(display)) {
    selectedDisplays.value = selectedDisplays.value.filter(d => d !== display);
  } else {
    selectedDisplays.value.push(display);
  }
};

const changeRecommend = (recommend: string) => {
  selectedRecommend.value = recommend;
};
</script>

<style scoped>
ion-button::part(native) {
  --border-radius: 20px;
  --padding: 10px;
}

ion-button[fill="solid"]::part(native) {
  --background: skyblue; /* 選択状態の背景色(単一選択と複数選択の両方で使える) */
  --color: white;    /* 選択状態の文字色 */
}

ion-button[fill="outline"]::part(native) {
  --background: white; /* 非選択状態の背景色 */
  --color: skyblue;       /* 非選択状態の文字色 */
  --border-color: skyblue; /* 非選択状態のボーダー色 */
}
</style>

今後について

アプリ開発もいよいよ終盤に差し掛かり、チーム一丸となって最後の仕上げに取り組んでいます。
このプロジェクトの進捗や準備の様子については、今後もブログやSNSで随時お伝えしていきます。

CES 2025への道のりを、ぜひ一緒に歩んでいただければうれしいです。
これからのNI+Cの挑戦に、どうぞご期待ください!

ページのトップへ