Nuxt3を使って子供向けの計算サイトを作る

投稿日:2024-02-14

Nuxt3を使って子供向けの計算サイトを作る

作品(GitHub)

こちらのリンクから飛ぶことができます。
Vercelでデプロイしたもの(リンク)

概要

専門学校での課外活動としてIntel株式会社様との企業プロジェクトに取り組みました。最終的に姉妹校を含めた発表会にて最優秀賞を頂きました✨今回はその中で学んだ事等を文章にしていきたいと思います(`・ω・´)

課題内容

教育の場で使用するパーセプトロンの仕組みについて学べるアプリケーションの制作でした。今回の難しかった点の一つとして、このパーセプトロンという物を誰でも理解できるようにする必要がありました。(単純パーセプトロンについては興味がある方は各自お調べください~...これが分かりやすかったです!)

制作の中で特に意識した所

中高生や機械学習の知識が無い人達が今回の題材であるパーセプトロンについて理解する為には"面白さ"が必要だと感じました。なぜなら、アプリケーション内でパーセプトロンの仕組みを検証するだけでは実際にどのような形で使われているのか分かりませんし、学習体験としても微妙だと感じます。

また、沢山の人が利用する想定なのでデザインや使いやすさを意識して制作に取り組みました。UIツールとしてuse-bootstrapを使いました(選んだ理由は私も開発に関わっているからです...(笑))

難しかったところと解決方法

  • データの管理

    Composablesを使ってページ遷移した際にもデータを保持するようにしました。これのおかげでデータの出力機能も簡単に実装できました。
    また、Refを使うことで値が変化した際にすぐ反映出来ます。(検証ページのスコア表示が分かりやすいと思います)

  • データの追加や削除

    データリストを作る際のいくつかの制約は条件分岐で実装します。

    また、v-forでループさせる事でリストの表示,追加,削除を実装しています。

    // データの削除
    const DeleteTaskData = (id: number) => {
      alertMessage.value = "";
      userData.value.dataList = userData.value.dataList.filter(
        (item: any) => item.id !== id
      );
    };
    
    // データの追加
    const MakeTaskData = () => {
      if (userData.value.dataList.length >= 10) {
        alertMessage.value = "データの数は10個までです。";
      } else {
        userData.value.dataList.push({
          id: maxId() + 1,
          title: "",
          weight: Number(),
          checked: false,
        });
      }
    };
    
    // 検証画面への遷移
    const playQuestion = () => {
      if (userData.value.dataList.length < 3) {
        alertMessage.value = "データの数は3個以上必要です。";
      } else if (userData.value.dataList.some((item) => item.title.trim() === "")) {
        alertMessage.value = "条件が空のデータが存在します。";
      } else if (userData.value.dataList.some((item) => item.weight == null)) {
        alertMessage.value = "重みが空のデータが存在します。";
      } else if (
        isNaN(userData.value.biasData) ||
        userData.value.titleList[0].do.trim() === ""
      ) {
        alertMessage.value = "タイトル欄に空のデータが存在します。";
      } else {
        checkedfalse();
        if (userData.value.debugMode === true) {
          navigateTo("/question");
        } else {
          navigateTo("/debug");
        }
      }
    };
    // 検証画面でのチェックボックスの初期化
    const checkedfalse = () => {
      userData.value.dataList.forEach((item: any) => {
        item.checked = false;
      });
    };
    
    // 現在のIDの最大値を取得
    const maxId = () => {
      let maxId = 0;
      userData.value.dataList.forEach((item: any) => {
        if (maxId < item.id) {
          maxId = item.id;
        }
      });
      return maxId;
    };
    
    // データの読み込み
    const loadData = (event: any) => {
      const file = event.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = function (e) {
          try {
            const data = JSON.parse((e.target?.result as string) || "");
            if (data.dataList && data.titleList && data.biasData) {
              userData.value.dataList = data.dataList;
              userData.value.titleList = data.titleList;
              userData.value.biasData = data.biasData;
            } else {
              console.error("Invalid data structure");
            }
          } catch (error) {
            console.error("Invalid JSON format");
          }
        };
        reader.readAsText(file);
      }
    };
    
    // データの出力
    const downloadData = () => {
      checkedfalse();
      const dataToDownload = {
        dataList: userData.value.dataList,
        titleList: userData.value.titleList,
        biasData: userData.value.biasData,
      };
      const dataStr = JSON.stringify(dataToDownload);
      const blob = new Blob([dataStr], { type: "application/json" });
      const url = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = userData.value.titleList[0].do + ".json";
      link.click();
      URL.revokeObjectURL(url);
    };
  • 〇×ゲームの実装

    データリストと現在の問題番号を紐づけて、〇×を押すことで問題番号を変更するようにしました。
    問題数はデータリストの長さを参照するようにすることで、長さ=現在の問題番号になった際に終了処理をするようにします。

今回学んだ内容

  • 技術的な内容
    授業だけでは分からなかったNuxt3の仕様や仕組みを学べました。フロンドエンドを学ぶ事で今後のバックエンド開発と繋げられるようになり、一つのシステムとしての完成度が上がるので、今回フロンドエンドを学べた事は非常に良い経験だと思います。
  • プロジェクト自体

    今回のプロジェクトの発表は学内で年に一度行われる進級制作展の学生代表プレゼンテーションでIntelさんだけでなく来場者の人に対しても発表しました。
    その中でスケジュール管理の難しさや、人前で企画を分かりやすく発表する難しさを知りました。余裕のあるスケジュールを組みましょう~