質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • JavaScript

    14298questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    476questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vue.js セレクトボックスで選択したオブジェクトの中身を表示したい

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 83

ebiebifry

score 2

 前提・実現したいこと

Vue.jsを使ってツールの制作を行っています。
https://codepen.io/ebifly/pen/RywWvg
上記のコードペンを見ていただけると分かりやすいと思うのですが
1.「名前を入力」→「追加」で入力した名前がセレクトボックスに追加される
2.リスト化されたものがセレクトボックスにも追加される
3.セレクトボックスで選ばれたものの「Status」が変更される
4.3と同時にセレクトボックスが消えて、選ばれたオブジェクトの内容が「選択されたのは[名前]Status:[ステータス]img:[イメージ番号]」の様に表示される
5.backボタンでセレクトボックスが現れてStatusが「a」に変更される
という動きを実装したいのですが、4,5の動きが上手くいかずアドバイスを頂きたいです。

 発生している問題・エラーメッセージ

発生している問題としてはオブジェクトの内容が上手く表示出来ないというのと、backボタンでStatusの変更が行えないということです。

 該当のソースコード

Vue.component('name-list',{
  template:'\
  <div>\
  <select v-if="!show" name="name-list" v-model="selected" @change="changeStatus">\
      <option value="">該当なし</option>\
      <option\
      v-for="(name, index) in names"\
      :value="name.id"\
      >{{ name.title }}\
      </option>\
    </select>\
    <p v-if="show">選択されたのは{{ names.title }}status:{{ names.status }} img:{{ names.img }}<button @click="changeBack">back</button></p>\
</div>\
  ',
  props: ['names'],
  data: function data() {
    return {
      selected: '',
      show: false,
    };
  },
  methods: 
    {
    changeStatus: function changeStatus(e){
    this.$emit('change-status', e.target.value);
    this.show = true;
    },
    changeBack: function changeBack(e){
    this.$emit('change-back', e.target.value);
    this.show = false;
    }
  }
 });

 var vm = new Vue({
   el: '#main',
   data: {
     newNameText: '',
     nextImg: 1,
     nextId: 0,
     names: []
   },
   methods: {
     addNewName: function () {
       if (this.newNameText !== '') {
         if (this.nextImg > 10) {
           this.nextImg = 1
         }
         this.names.push({
           img: this.nextImg++,
           id: this.nextId++,
           title: this.newNameText,
           status: 'a'
         })
       }
       this.newNameText = ''
     },
     updateName: function updateName(id, name){
      this.names[id].title = name
     },
     changeB: function changeB(id){
       this.names[id].status = 'b'
     },
     changeC: function changeC(id){
       this.names[id].status = 'c'
     },
     changeBack: function changeBack(id){
       this.names[id].status = 'a'
     }
   }
 })

vm.$mount('#main');

 試したこと

<div>
  changeB
    <name-list
    :names="names"
    :title="names.title"
    :img="names.img"
    :status="names.status"
    @change-status="changeB"
    @change-back="changeBack"
    ></name-list>
</div>
 Vue.component('name-list',{
  template:'\
  <div>\
  <select v-if="!show" name="name-list" v-model="selected" @change="changeStatus">\
      <option value="">該当なし</option>\
      <option\
      v-for="(name, index) in names"\
      :value="name.id"\
      >{{ name.title }}\
      </option>\
    </select>\
    <p v-if="show">選択されたのは{{ title }}status:{{ status }} img:{{ img }}<button @click="changeBack">back</button></p>\
</div>\
  ',
  props: ['names', 'title', 'status', 'img']


上記の様にprops周りを書き換えても上手くいきませんでした_(:3 」∠)_
ご教授のほどよろしくお願いしますm(_ _)m

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

ざっと見てみましたが直すところは name-list だけで済みそうです。

まず表示部分ですが names は配列なので、現在選択している項目の id と一致する names の中の要素を取り出さなければなりません。
Array.prototype.find() を使えば一発で要素を取得できますが、後述する内容で添字が必要になるので、添字を取得して、その添字を使って要素を取得するようにます。

  computed: {
    selectedItem: function selectedItem() {
      // 選択項目の id と一致する names 配列の要素を取得
      return this.names[this.selectedIndex];
    },
    selectedIndex: function selectedIndex() {
      // 選択項目の id と一致する names 配列の添字を取得
      return this.names.findIndex(i => i.id === this.selected);
    },
  }, 

これで選択項目に該当する names の要素を表示する準備が整ったので、

<p v-if="show">選択されたのは{{ selectedItem.title }}status:{{ selectedItem.status }} img:{{ selectedItem.img }}<button @click="changeBack">back</button></p>\

のようにしてやります。

次に、ステータスの更新では、下記に示す親コンポーネントの changeB メソッド等を見れば分かるように、
選択項目の names 配列での添字を $emit で送る必要があります。

     changeB: function changeB(id){
       this.names[id].status = 'b'
     }

選択項目の names 配列での添字は最初に示したコードにて this.selectedIndex で取得できるようにしてありますので、

    changeStatus: function changeStatus(){
      this.$emit('change-status', this.selectedIndex);
      if (this.selectedIndex !== false) { // 該当なしの場合は表示しない
        this.show = true;
      }
    },
    changeBack: function changeBack(){
      this.$emit('change-back', this.selectedIndex);
      this.show = false;
      this.selected = ''; // 該当なしに選択状態を戻す
    },

このようになります。

それと、ステータスをプロパティにしてやれば、ステータスの数だけ更新用のメソッドが増えるようなことはなくなると思いますよ。v-model を使うともうちょっとスマートに書けると思います。

<name-list status="b" @change-status="changeStatus" .....></name-list>
this.$emit('change-status', this.selectedIndex, this.status);
this.$emit('change-status', this.selectedIndex, 'a'); // change-back -> change-status
changeStatus: function changeStatus(id, status){
  this.names[id].status = status
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/24 18:17

    丁寧な回答ありがとうございましたm(_ _)m
    とても分かりやすく、無事実装することが出来ました!
    statusをプロパティにすることで、メゾットを減らせたのは目からウロコでした。
    本当にありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    14298questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    476questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。