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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

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

JavaScript

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

Q&A

解決済

1回答

2595閲覧

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

ebiebifry

総合スコア8

Vue.js

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

JavaScript

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

0グッド

1クリップ

投稿2018/05/23 08:45

前提・実現したいこと

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

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

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

該当のソースコード

js

1Vue.component('name-list',{ 2 template:'\ 3 <div>\ 4 <select v-if="!show" name="name-list" v-model="selected" @change="changeStatus">\ 5 <option value="">該当なし</option>\ 6 <option\ 7 v-for="(name, index) in names"\ 8 :value="name.id"\ 9 >{{ name.title }}\ 10 </option>\ 11 </select>\ 12 <p v-if="show">選択されたのは{{ names.title }}status:{{ names.status }} img:{{ names.img }}<button @click="changeBack">back</button></p>\ 13</div>\ 14 ', 15 props: ['names'], 16 data: function data() { 17 return { 18 selected: '', 19 show: false, 20 }; 21 }, 22 methods: 23 { 24 changeStatus: function changeStatus(e){ 25 this.$emit('change-status', e.target.value); 26 this.show = true; 27 }, 28 changeBack: function changeBack(e){ 29 this.$emit('change-back', e.target.value); 30 this.show = false; 31 } 32 } 33 }); 34 35 var vm = new Vue({ 36 el: '#main', 37 data: { 38 newNameText: '', 39 nextImg: 1, 40 nextId: 0, 41 names: [] 42 }, 43 methods: { 44 addNewName: function () { 45 if (this.newNameText !== '') { 46 if (this.nextImg > 10) { 47 this.nextImg = 1 48 } 49 this.names.push({ 50 img: this.nextImg++, 51 id: this.nextId++, 52 title: this.newNameText, 53 status: 'a' 54 }) 55 } 56 this.newNameText = '' 57 }, 58 updateName: function updateName(id, name){ 59 this.names[id].title = name 60 }, 61 changeB: function changeB(id){ 62 this.names[id].status = 'b' 63 }, 64 changeC: function changeC(id){ 65 this.names[id].status = 'c' 66 }, 67 changeBack: function changeBack(id){ 68 this.names[id].status = 'a' 69 } 70 } 71 }) 72 73vm.$mount('#main');

試したこと

html

1<div> 2 changeB 3 <name-list 4 :names="names" 5 :title="names.title" 6 :img="names.img" 7 :status="names.status" 8 @change-status="changeB" 9 @change-back="changeBack" 10 ></name-list> 11</div>

js

1 Vue.component('name-list',{ 2 template:'\ 3 <div>\ 4 <select v-if="!show" name="name-list" v-model="selected" @change="changeStatus">\ 5 <option value="">該当なし</option>\ 6 <option\ 7 v-for="(name, index) in names"\ 8 :value="name.id"\ 9 >{{ name.title }}\ 10 </option>\ 11 </select>\ 12 <p v-if="show">選択されたのは{{ title }}status:{{ status }} img:{{ img }}<button @click="changeBack">back</button></p>\ 13</div>\ 14 ', 15 props: ['names', 'title', 'status', 'img']

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

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

javascript

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

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

html

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

のようにしてやります。

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

javascript

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

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

javascript

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

このようになります。

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

html

1<name-list status="b" @change-status="changeStatus" .....></name-list>

javascript

1this.$emit('change-status', this.selectedIndex, this.status); 2this.$emit('change-status', this.selectedIndex, 'a'); // change-back -> change-status

javascript

1changeStatus: function changeStatus(id, status){ 2 this.names[id].status = status 3}

投稿2018/05/23 18:17

yhg

総合スコア2161

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ebiebifry

2018/05/24 09:17

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問