【Vue.js】Vuexを使って確認画面で値を表示させる

# Vuexを使って確認画面で値を表示させる

## 背景
Vue-cliでアンケートフォーム作成中
Vuexを使って答えた解答を最後、確認画面で表示させたい

## 実装
### 値を取得する

- ```@change```でメソッド起動
- ```this.$store.commit('updateGender', e.target.value)```で値を取得して、mutationsを実行する

```BasicForm.vue

<template>
<div>
  <div class="form">
    <div class="header">
      <p id="step">STEP1</p>
      <p id="inst">お客様の情報を入力してください</p>
    </div>
    <div class="body">
      <p class="genre">-性別-</p>
        <label><input type="radio" name="gender" value="男性" @change="updateGender">男性</label>
        <label><input type="radio" name="gender" value="女性" @change="updateGender">女性</label>
      <p class="genre">-生年月日-</p>
      <select name="year" id="id_year" @change="updateYear">
        <option v-for="(year, key) in years" :key="key">{{ year }}</option>
      </select>年
      <select name="month" id="id_month" @change="updateMonth">
        <option v-for="(month, key) in months" :key="key">{{ month }}</option>
      </select>月
      <select name="day" id="id_day" @change="updateDay">
        <option v-for="(day, key) in days" :key="key">{{ day }}</option>
      </select>日
    </div>
  </div>
  <div class="button-group">
    <router-link to="/questionnaire" class="button">次へ進む ＞</router-link>
  </div>
</div>
</template>

<script>

//省略

  methods: {
    updateGender (e) {
      this.$store.commit('updateGender', e.target.value)
    },
    updateYear (e) {
      this.$store.commit('updateYear', e.target.value)
    },
    updateMonth (e) {
      this.$store.commit('updateMonth', e.target.value)
    },
    updateDay (e) {
      this.$store.commit('updateDay', e.target.value)
    },
  }
}
</script>
```


### 取得した値をVUexストアのstateに格納する
- mutationsが起動して、設定しいたstateのプロパティに値を格納する

```index.js
"use strict"

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//どこからでも参照できる唯一の情報源store
const store = new Vuex.Store({
  state: {
    gender: '',
    year: '',
    month: '',
    day: '',
    q1: '',
    q2: '',
    q3: '',
    consultation: '',
  },
  mutations: {
    // ページ1
    updateGender (state, gender) {
      state.gender = gender
    },
    updateYear (state, year) {
      state.year = year += '年'
    },
    updateMonth (state, month) {
      state.month = month += '月'
    },
    updateDay (state, day) {
      state.day = day += '日'
    },
    // ページ2
    updateQ1 (state, q1) {
      state.q1 = q1
    },
    updateQ2 (state, q2) {
      state.q2 = q2
    },
    updateQ3 (state, q3) {
      state.q3 = q3
    },
    // ページ3
    updateConsultation (state, consultation) {
      state.consultation = consultation
    },
  },
});

export default store

```


### stateに格納した値をVueコンポーネントで表示させる

- {{}}の中身にstateで設定したプロパティ名を記述する
- mapStateを使用して表示する際の記述を省略している

```確認画面.vue
<template>
<div>
  <div class="form">
    <div class="header">
      <p id="step">STEP4</p>
      <p id="inst">以下の内容をご確認ください</p>
    </div>
    <div class="body">
      <div>
        <p class="genre">-性別-</p>
        <p class="answer">{{ gender }}</p>
      </div>
      <div>
        <p class="genre">-生年月日-</p>
        <p class="answer">{{ year }}{{ month }}{{ day }}</p>
      </div>
      <div>
        <p class="genre">-現在、生命保険に加入されていますか？-</p>
        <p class="answer">{{ q1 }}</p>
      </div>
      <div>
        <p class="genre">-現在入院中ですか。または、最近3ヶ月以内に医師の診断・検査の結果、入院・手術をすすめられたことはありますか？-</p>
        <p class="answer">{{ q2 }}</p>
      </div>
      <div>
        <p class="genre">-過去5年以内に、病気やけがで、手術を受けたことまたは継続して7日以上の入院をしたことはありますか？-</p>
        <p class="answer">{{ q3 }}</p>
      </div>
      <div>
        <p class="genre">-ご相談内容-</p>
        <p class="answer">{{ consultation }}</p>
      </div>
    </div>
  </div>
  <div class="button-group">
    <router-link to="/consultation" class="button">前へ戻る ＞</router-link>
    <router-link to="/confirmation" class="button">送信 ＞</router-link>
  </div>
</div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState({
      gender: 'gender',
      year: 'year',
      month: 'month',
      day: 'day',
      q1: 'q1',
      q2: 'q2',
      q3: 'q3',
      consultation: 'consultation',
    })
  }
}
</script>

<style scoped lang="scss">
* {
  // outline: auto;
	margin:0; padding:0; 		/*全要素のマージン・パディングをリセット*/
  max-width: 100%;
}

#step{
  background: #1e90ff;
  color: #fff;
  font-size: 2px;
  margin: 0;
  max-width: 40px;
  padding: 2px;
  text-align: center;
}

#inst {
  font-size: 12px;
  color: #696969;
  text-align: center;
  padding-bottom: 10px;
}

.header {
  background: #afeeee;
  margin: 0%;
  padding: 0%;
  line-height: 10px;
  border-bottom: solid 1px #48d1cc;
}

.body {
  font-size: 9px;
  margin: 10px;
  padding-bottom: 10px;
  line-height: 30px;
  text-align: left;
}

.genre {
  color: #1e90ff;
  text-align: left;
  line-height:200%
}

.answer {
  margin: 0 0 0 10px;
}

textarea {
  border: 1px solid #dcdcdc;
}

.form{
  max-width: 80%;
  margin-top: 80px;
  margin-left: auto;
  margin-right: auto;
  border: 1px solid #48d1cc;
  border-bottom: 0.5px solid #000;
}

.button-group{
  text-align: center;
}

.button {
  background-color: #40e0d0;
  color: #fff;
  border: solid 1px #48d1cc;
  margin-top: 1rem;
  padding: 5px 10px;
  border-radius: 0.5rem 0.5rem;
  text-decoration: none;
  display:inline-block;
  margin: 10px;
}
</style>

```
## おまけ
以下確認画面です。

![スクリーンショット 2021-03-14 18.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979873/36da43dd-574c-c925-3f19-3f6fe55820b6.png)