【リベンジ】「何食べたい？」に対して「なんでもいい」以外の言葉、探してみませんか？#Webアプリ #料理 #献立 #家庭内戦争回避 #夕飯戦争回避

:warning:**家庭内戦争**:warning:を回避したく、[前回の記事](https://qiita.com/yui-kouy/items/5dc0db657e29e677bed6)にて投稿していましたが、今回[Bootstrap](https://qiita.com/yui-kouy/items/f52e6715843f760bc617)を使用して見やすくしたいと思ったのでバージョンアップいたします。

#リベンジ「なんでもいい」以外の言葉を探すために！
アプリをバージョンアップしました！
前回よりはシンプルにはなりましたが見やすくなったのではないでしょうか？
どうぞお使いください:sparkles:

https://gifted-hawking-bb8e05.netlify.app/

【変更点】
・料理の作り方を削除→英語を翻訳できていないので不要と判断
・タブを削除して一画面に表示
・買い物メモ欄を登録内容ごとに枠づけ
・「同じブラウザであれば」という制限付きですがデータを保存する設定を追加

#アプリ全体図（前回との比較）

|前回|今回|
|:-:|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/7ce7342a-b1d9-3e9e-9833-a38d1900f28c.jpeg">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/5e0fd17c-5106-af88-a604-c5d0cb823ca0.jpeg">|


#CodePen
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="porVgPB" data-user="yui-ko" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yui-ko/pen/porVgPB">
  料理とお買い物メモ_バージョンアップ</a> by yui-ko (<a href="https://codepen.io/yui-ko">@yui-ko</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#各機能ごと
料理画像の取得・表示、お買い物メモについて記載します。

##料理画像の取得・表示
料理API（料理情報をランダムで取得）を使用して、画像・料理名・Youtubeリンク・元サイトの情報を取得。
表示する画像は画面に対して50%表示。

:yellow_heart:**HTML**:yellow_heart:

```HTML
<!--料理画像エリア-->
  <div class="row my-3">
    <div class="col-sm-8 mx-auto">
      <a href="" class="btn btn-primary">他の料理も見たい場合は押してください</a><br><br>
      <img id="mypict" src="https://i.postimg.cc/63mKxMZP/I8d1-Di-HQY8e5-Meu1635871349-1635871569.jpg" class="contain" width=50%><br>
    </div>
    <div class="col-sm-12 mx-auto">
      <h2 id="myname">料理名</h2>
      <p id="bio1">★☆★☆★　Youtube　★☆★☆★</p>
      <p id="bio2">★☆★☆★　引用元リンク　★☆★☆★</p><br>
    </div>
  </div>
```

:blue_heart:**JavaScript**:blue_heart:

```JS
window.addEventListener('DOMContentLoaded', async function() {
  console.log('DOMの構築が完了しました');
  let response;
  try {
    // axiosでAPIを叩く
    response = await axios.get('https://www.themealdb.com/api/json/v1/1/random.php');
    // 取得できたデータをログに表示
    const myInfo = response.data.meals[0];
    console.log(myInfo);
    // IDが「myname」である要素の中身に料理名をセット
    document.getElementById('myname').innerHTML = myInfo.strMeal;
	  // IDが「bio1～3」である要素の中身に料理情報等をセット
    document.getElementById('bio1').innerHTML = `★☆★☆★　Youtube　★☆★☆★<br>${myInfo.strYoutube}`;
    document.getElementById('bio2').innerHTML = `★☆★☆★　引用元サイト★☆★☆★<br>${myInfo.strSource}`;
    // IDが「mypict」である要素のソースに写真URLをセット
    document.getElementById('mypict').src = `${myInfo.strMealThumb}`;
  } catch {
    // try内でなんらかのエラーがあったとき
    console.error('エラー:', error);
  }
})
```
##買い物メモ
買い物メモを登録することができます。

**変更点①**
「同じブラウザであれば」という制限付きですがお買い物メモの保存に成功しています。

**変更点②**
入力エリアに入力していても、何を入れるかの表示を残すことに成功しています。

|前回|今回|
|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/2aa6a504-4aba-b19f-ae1d-701b05c4f3c9.png)|![kaimonomemoran.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/840729af-027c-5205-631c-aa69838abec5.png)|

:yellow_heart:**HTML**:yellow_heart:

```HTML
<!-- 買い物メモエリア -->
  <div class="row my-12 p-3 bg-success">
    <div class="col-sm-8 mx-auto">
        <h1>お買い物メモ</h1>
    </div>
  </div>

<!-- 買い物メモ入力行 -->
  <div class="row my-3">
    <div class="col-sm-8 mx-auto">
        <div class="form-floating">
        <textarea v-model:value="task" class="form-control" placeholder="Leave a comment here" id="floatingTextarea"></textarea>
        <label for="floatingTextarea">買い物メモを入力</label><br>
        ≪登録内容≫<br>「{{ task }}」を登録するよ。<br>OK！ボタンを押してね。<button v-on:click="addTask" class="btn btn-success">OK！</button>
        </div>
    </div>
  </div>

<!-- 買い物メモをすべてクリアするボタン -->
  <div class="row my-3">
    <div class="col-sm-8 mx-auto">
        <p class="text-danger">All Clearして大丈夫かな？</p>
        <button v-on:click="clearAll" class="btn btn-danger">All Clear</button>
    </div>
  </div>

<!-- 買い物メモが追加されると表示される部分 -->
  <div class="row my-3">
    <div class="col-sm-8 mx-auto">
        <p v-for="todo in todoList" class="alert alert-primary">{{ todo }}</p>
    </div>
  </div>
</div> 
```

:blue_heart:**JavaScript**:blue_heart:

```JS
const app = new Vue({
  el: '#app', // Vueが管理する一番外側のDOM要素
  data: {
    // Vue内部で使いたい変数は全てこの中に定義する
    task: '',
    todoList: [], // これは配列
  },
  mounted() {
    //ローカルストレージ内のタスクを読み込む(JSON⇒配列に変換する)
    const tasks = JSON.parse(localStorage.getItem('task'));
    //中身があれば配列にセット※中身がNULLなら何もしない
    if(tasks) {      
      this.todoList = tasks;
    }    
  },
  methods: {
    // 関数はここ
    addTask: function() {
      console.log('次の買い物メモが追加されました：', this.task);
      // 配列の先頭に現在のタスク内容を追加する（最後尾の場合はpush）
      this.todoList.unshift(this.task);
      //ローカルストレージにタスクを保存（配列⇒JSONに変換する）
      localStorage.setItem('task', JSON.stringify(this.todoList));
      console.log('現在の買い物メモ一覧：', this.todoList);
    },
    // 以下を追加、関数名はなんでもよい
    clearAll: function() {
      this.todoList = [];
      console.log('全て消去されました');
    },
  },
});
```

#Bootstrapについて
導入方法と日本語リファレンスについて別記事にまとめました。

https://qiita.com/yui-kouy/items/f52e6715843f760bc617


#まとめ
前回も思いましたが、Webアプリを簡単に作れることが驚きました。
そしてBootstrapは便利でした。Cssと組み合われば、可能性は無限大ですね。