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

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

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

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

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

1549閲覧

テーブルでクリックした行の下に新たな行を展開させたい

退会済みユーザー

退会済みユーザー

総合スコア0

Vue.js

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

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/01/13 12:35

編集2020/01/13 12:38

Nuxt.jsとbootstrap-vueを使っています。

クリックした行の下に新たな行を展開させたいです。

クリックした行だけ展開させたいのですが、
現状はほかの行のイベントも動いてしまい展開されてしまいます。
(原因はv-forで回していて列に同じイベント@click="click"がついているからです)

どうしたら、思い通りの動作を実行できるでしょうか?
ご教授よろしくお願い致します。

nuxt

1<template> 2 <div> 3 <b-table-simple class="card"> 4 <b-thead> 5 <b-tr> 6 <b-th v-for="field in fields" :key="field.key">{{ field.label }}</b-th> 7 </b-tr> 8 </b-thead> 9 <b-tbody v-for="item in items" :key="item.sample1"> 10 <b-tr @click="click"> 11 <b-td>{{ item.sample1 }}</b-td> 12 <b-td>{{ item.sample2 }}</b-td> 13 <b-td>{{ item.sample3 }}</b-td> 14 </b-tr> 15 <b-tr v-show="show" v-for="subItem in item.subItems" :key="subItem.sample1"> 16 <b-td>{{ subItem.sample1 }}</b-td> 17 <b-td>{{ subItem.sample2 }}</b-td> 18 <b-td>{{ subItem.sample3 }}</b-td> 19 </b-tr> 20 </b-tbody> 21 </b-table-simple> 22 </div> 23</template> 24 25<script> 26export default { 27 data () { 28 return { 29 show : false, 30 fields: [ 31 {key: 'sample1', label: 'サンプルタイトル1'}, 32 {key: 'sample2', label: 'サンプルタイトル2'}, 33 {key: 'sample3', label: 'サンプルタイトル3'}, 34 ], 35 items: [ 36 { 37 sample1: 'サンプル1', 38 sample2: 'サンプル2', 39 sample3: 'サンプル3', 40 subItems: [ 41 { 42 sample1: 'サンプル1', 43 sample2: 'サンプル2', 44 sample3: 'サンプル3', 45 }, 46 { 47 sample1: 'サンプル1', 48 sample2: 'サンプル2', 49 sample3: 'サンプル3', 50 }, 51 ] 52 }, 53 { 54 sample1: 'サンプル1', 55 sample2: 'サンプル2', 56 sample3: 'サンプル3', 57 subItems: [ 58 { 59 sample1: 'サンプル1', 60 sample2: 'サンプル2', 61 sample3: 'サンプル3', 62 }, 63 { 64 sample1: 'サンプル1', 65 sample2: 'サンプル2', 66 sample3: 'サンプル3', 67 }, 68 ] 69 } 70 ], 71 } 72 }, 73 methods: { 74 click() { 75 this.show = !this.show 76 } 77 } 78} 79</script>

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

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

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

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

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

guest

回答1

0

ベストアンサー

items配列の各要素にshowを持たせればよいと思います。
現状showがひとつしかないので、items配列の何番目がclickされたのを判定せずに全部展開してしまっている状態ですね。
v-forからindexを取得して、clickイベントにindexを渡せば、items配列の特定の要素だけを開閉できるようになります。

nuxt

1<template> 2 <div> 3 <b-table-simple class="card"> 4 <b-thead> 5 <b-tr> 6 <b-th v-for="field in fields" :key="field.key">{{ field.label }}</b-th> 7 </b-tr> 8 </b-thead> 9 <b-tbody v-for="(item, index) in items" :key="item.sample1"> 10 <b-tr @click="click(index)"> 11 <b-td>{{ item.sample1 }}</b-td> 12 <b-td>{{ item.sample2 }}</b-td> 13 <b-td>{{ item.sample3 }}</b-td> 14 </b-tr> 15 <b-tr v-show="item.show" v-for="subItem in item.subItems" :key="subItem.sample1"> 16 <b-td>{{ subItem.sample1 }}</b-td> 17 <b-td>{{ subItem.sample2 }}</b-td> 18 <b-td>{{ subItem.sample3 }}</b-td> 19 </b-tr> 20 </b-tbody> 21 </b-table-simple> 22 </div> 23</template> 24 25<script> 26export default { 27 data () { 28 return { 29 fields: [ 30 {key: 'sample1', label: 'サンプルタイトル1'}, 31 {key: 'sample2', label: 'サンプルタイトル2'}, 32 {key: 'sample3', label: 'サンプルタイトル3'}, 33 ], 34 items: [ 35 { 36 show : false, 37 sample1: 'サンプル1', 38 sample2: 'サンプル2', 39 sample3: 'サンプル3', 40 subItems: [ 41 { 42 sample1: 'サンプル1', 43 sample2: 'サンプル2', 44 sample3: 'サンプル3', 45 }, 46 { 47 sample1: 'サンプル1', 48 sample2: 'サンプル2', 49 sample3: 'サンプル3', 50 }, 51 ] 52 }, 53 { 54 show : false, 55 sample1: 'サンプル1', 56 sample2: 'サンプル2', 57 sample3: 'サンプル3', 58 subItems: [ 59 { 60 sample1: 'サンプル1', 61 sample2: 'サンプル2', 62 sample3: 'サンプル3', 63 }, 64 { 65 sample1: 'サンプル1', 66 sample2: 'サンプル2', 67 sample3: 'サンプル3', 68 }, 69 ] 70 } 71 ], 72 } 73 }, 74 methods: { 75 click(index) { 76 this.items[index].show = !this.items[index].show 77 } 78 } 79} 80</script>

あと今回の質問とは関係ないですが、ブラウザの開発者モードで確認すると

[Vue warn]: Duplicate keys detected: 'サンプル1'.

というエラーがでています。
サンプルコードだとは思いますが、一応:keyには一意になる値が必ずくるように実装するのをお忘れなく。

追記

Vue.jsについては詳しくないので、気になって:keyについて調べてみました。
https://qrunch.net/@rokujiro/entries/wkreYi4Opa4Wa3iU
上記の説明によるとなるべく配列の中に一意の値をもつプロパティを持たせたほうがいいようですね。
そうなると、clickイベントでindexを渡すよりも、要素のkeyになるプロパティを渡して、
それに一致すつ配列の要素を探してshowを切り替えたほうがいいみたいですね。

nuxt

1<template> 2 <div> 3 <b-table-simple class="card"> 4 <b-thead> 5 <b-tr> 6 <b-th v-for="field in fields" :key="field.key">{{ field.label }}</b-th> 7 </b-tr> 8 </b-thead> 9 <b-tbody v-for="item in items" :key="item.id"> 10 <b-tr @click="click(item.id)"> 11 <b-td>{{ item.sample1 }}</b-td> 12 <b-td>{{ item.sample2 }}</b-td> 13 <b-td>{{ item.sample3 }}</b-td> 14 </b-tr> 15 <b-tr v-show="item.show" v-for="subItem in item.subItems" :key="subItem.id"> 16 <b-td>{{ subItem.sample1 }}</b-td> 17 <b-td>{{ subItem.sample2 }}</b-td> 18 <b-td>{{ subItem.sample3 }}</b-td> 19 </b-tr> 20 </b-tbody> 21 </b-table-simple> 22 </div> 23</template> 24 25<script> 26export default { 27 data () { 28 return { 29 fields: [ 30 {key: 'sample1', label: 'サンプルタイトル1'}, 31 {key: 'sample2', label: 'サンプルタイトル2'}, 32 {key: 'sample3', label: 'サンプルタイトル3'}, 33 ], 34 items: [ 35 { 36 id: 1123, 37 show : false, 38 sample1: 'サンプル1', 39 sample2: 'サンプル2', 40 sample3: 'サンプル3', 41 subItems: [ 42 { 43 id: 1, 44 sample1: 'サンプル1', 45 sample2: 'サンプル2', 46 sample3: 'サンプル3', 47 }, 48 { 49 id: 2, 50 sample1: 'サンプル1', 51 sample2: 'サンプル2', 52 sample3: 'サンプル3', 53 }, 54 ] 55 }, 56 { 57 id: 1124, 58 show : false, 59 sample1: 'サンプル1', 60 sample2: 'サンプル2', 61 sample3: 'サンプル3', 62 subItems: [ 63 { 64 id: 1, 65 sample1: 'サンプル1', 66 sample2: 'サンプル2', 67 sample3: 'サンプル3', 68 }, 69 { 70 id: 2, 71 sample1: 'サンプル1', 72 sample2: 'サンプル2', 73 sample3: 'サンプル3', 74 }, 75 ] 76 } 77 ], 78 } 79 }, 80 methods: { 81 click(id) { 82 this.items.forEach(item => { 83 if (item.id == id) item.show = !item.show 84 }) 85 } 86 } 87} 88</script>

投稿2020/01/16 09:16

編集2020/01/16 09:51
storm3

総合スコア328

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

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

退会済みユーザー

退会済みユーザー

2020/03/07 14:10

回答ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問