【Vue x Firestore】セレクトボックスで初期表示の文字のみ色を変える


#セレクトボックスで初期表示文字のみ色を変える

自分自身ポートフォリオ作成時に沼ってしまい時間を要してしまった為、備忘録として置いておきます。

結論を先に言うと「undefind」となってしまう場合は、「空の文字列」を入れるようにする。

```html:mypage.vue
 <modal class="modal-inner" v-scroll-lock="open" name="edit" :width="1100" :height="740">
            <div data-modal="edit" aria-expanded="true" class="vm--overlay">
              <div class="vm--top-right-slot"></div>
            </div>
            <div class="modal-header flex">
              <h2 class="profile-tll flex">プロフィールを編集する</h2>
              <hr class="separate" />
            </div>
            <div class="modal-body">
              <div class="profile-inner flex">
                <div class="profile-contens flex">
                  <div class="profile-img-inner flex">
                    <img
                      src="../assets/アイコン.jpg"
                      width="200"
                      height="200"
                      class="profile-img"
                      alt="プロフィール画像"
                    />
                    <button class="profile-txt profile-update">プロフィール画像を編集する</button>
                  </div>
                  <div class="line"></div>
                  <div class="profile-items flex">
                    <div class="profile-contens flex">
                      <input type="text" class="profile-item" placeholder="名前" v-model="name" />
                    </div>
                    <div class="profile-contens flex">
                      <select
                        class="profile-select"
                        v-model="sex"
                        :style="{ color: sex == '' ? 'gray' : 'white' }"
                      >
                        <option class="profile-item" value hidden>性別</option>
                        <option
                          v-for="sex in sexs"
                          :value="sex.name"
                          :key="sex.id"
                          class="profile-item"
                          style="color: white;"
                        >{{ sex.name }}</option>
                      </select>
                    </div>
        
                  ~ 省略 ~

                  <button
                    class="hide-btn flex"
                    @click="
                      hide();
                      closeModal();
                    "
                  >×</button>
                </div>
                <button @click="updateBtn" class="update-btn flex">更新</button>
              </div>
            </div>
          </modal>
```

```javascript:mypage.vue
export default {
  data() {
    return {
      name: "",
      sex: "",
      sexs: [{ name: "男性" }, { name: "女性" }, { name: "その他" }],
      age: "",
      ages: [
        { name: "10際未満" },
        { name: "10 ~ 19歳" },
        { name: "20 ~ 29歳" },

         ~ 省略 ~
       
      ],
      access: "",
      accesses: [
        { name: "北海道" },
        { name: "青森県" },
        { name: "岩手県" },

         ~ 省略 ~
       
      ],
      profession: "",
      professions: [
        { name: "公務員" },
        { name: "会社員" },
        { name: "自営業" },

         ~ 省略 ~

      ],
      selfpr: "",
      genre: "",
      genres: [
        { id: 0, name: "ジャンル" },
        { id: 1, name: "アクション" },
        { id: 2, name: "ドラマ" },
        { id: 3, name: "恋愛" },

                 ~ 省略 ~

      ],
      favMovie: "",
      uploadedImage: "",
      profileData: {},
      listData:[],
      open: false,
    };
  },
  components: {
    Header,
  },
  methods: {
    // updateBtn()が押下されたら、dbインスタンスを初期化して"posts"という名前のコレクションへの参照
    updateBtn() {
      firebase
        .firestore()
        .collection("users")
        .doc(this.$route.params.uid)
        //現在のURLのパラメーターを取得。
        .set(
          {
            name: this.name,
            sex: this.sex,
            age: this.age,
            access: this.access,
            selfpr: this.selfpr,
            profession: this.profession,
            uploadedImage: this.uploadedImage,
            genre: this.genre,
            favMovie: this.favMovie,
            time: firebase.firestore.FieldValue.serverTimestamp()
            //サーバ側で値設定
          },
          { merge: true }
          //set()でmergeをtrueにすると、上書き。updetaと同様。
        );
      this.$swal({
        title: "内容確認",
        text: "この内容で投稿しますか？",
        icon: "info",
        buttons: true,
        dangerMode: true
      }).then(willDelete => {
        if (willDelete) {
          this.$swal("投稿しました。", {
            icon: "success"
          });
          this.$router.go({
            path: `/mypage/${this.$route.params.uid}`,
            force: true
          });
          //プロフィール編集されたらページをリロード
        } else {
          this.$swal("キャンセルしました。");
        }
      });
    },

   ~ 省略 ~  

  },
  created() {
    const currentUser = firebase.auth().currentUser;

    if (currentUser) {
      firebase
        .firestore()
        .collection("users")
        .doc(this.$route.params.uid)
        .get()
        .then(snapshot => {
  　　　　 this.name = this.profileData.name || "";
          this.sex = this.profileData.sex || "";
          this.age = this.profileData.age || "";
          this.access = this.profileData.access || "";
          this.selfpr = this.profileData.selfpr || "";
          this.profession = this.profileData.profession || "";
          this.uploadedImage = this.profileData.uploadedImage || "";
          this.genre = this.profileData.genre || "";
          this.favMovie = this.profileData.favMovie || "";
        });
    }
```

```html:mypage.vue
<select class="profile-select" v-model="sex" :style="{ color: sex == '' ? 'gray' : 'white' }">
 <option class="profile-item" value hidden>性別</option>
 <option v-for="sex in sexs" :value="sex.name" :key="sex.id" class="profile-item" style="color: white;">{{ sex.name }}</option>
</select>
```

:style="{ color: sex == '' ? 'gray' : 'white' }"と三項演算子を使用して未選択であればグレー、選択済であれば白色としています。

```javascript:mypage.vue
  created() {
    const currentUser = firebase.auth().currentUser;

    if (currentUser) {
      firebase
        .firestore()
        .collection("users")
        .doc(this.$route.params.uid)
        .get()
        .then(snapshot => {
          this.name = this.profileData.name || "";
          this.sex = this.profileData.sex || "";
          this.age = this.profileData.age || "";
          this.access = this.profileData.access || "";
          this.selfpr = this.profileData.selfpr || "";
          this.profession = this.profileData.profession || "";
          this.uploadedImage = this.profileData.uploadedImage || "";
          this.genre = this.profileData.genre || "";
          this.favMovie = this.profileData.favMovie || "";
        });
    }
```
上記のように「this.name = this.profileData.name || ""」とせず「this.name = this.profileData.name」としてしまうとundefindとなってしまう。
その時は「this.name = this.profileData.name || ""」を加えて空の文字列を入れるようにします。