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

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

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

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

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

HTML

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

CSS

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

Q&A

解決済

1回答

2455閲覧

【Vue.js】モーダル内の要素にテーブルの行ごとのIDを渡したい

im05ttbbh

総合スコア18

Vue.js

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

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

HTML

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

CSS

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

0グッド

0クリップ

投稿2021/03/03 00:58

実現したいこと

Vue.jsでモーダルの中の要素にテーブルの行ごとのIDを渡したい

状況

  1. Vue Materialのテーブルコンポーネントを使用
  2. Modalコンポーネントを作成し、ラップした要素をモーダル表示できるように実装
  3. ChildFormコンポーネントを作成し、Modalコンポーネントでラッピング
  4. Parent.vueでthis.$refs.childを使用し、ボタンをクリックすると子のModalにあるopenModalを発火させる(こちらを参照にしました

↑のような状況で親であるParent.vueからChildForm.vueにIDデータを渡したい。

問題の箇所

ChildForm.vueにて、propsとして渡したitemIdを表示させようとしたが、常にID『2』がモーダルフォームに表示される

Vue

1<template> 2 <div> 3 {{ itemId }} 4 </div> 5</template>

問題箇所のアニメーションgif

![イメージ説明

該当のソースコード

【Parent.vue】

Vue

1<template> 2 <div> 3 <md-table v-model="products"> 4 <md-table-row slot="md-table-row" slot-scope="{ item }"> 5 <md-table-cell md-label="ID">{{ item.id }}</md-table-cell> 6 <md-table-cell md-label="ユーザー">{{ item.user }}</md-table-cell> 7 <md-table-cell md-label="アクション"> 8 <button @click="onClickOpenModal">ボタン</button> 9 <Modal ref="child"> ←親から子のメソッドにアクセスできるように実装 10 <template #content> 11 <ChildForm :item-id="item.id" /> 12 </template> 13 </Modal> 14 </md-table-cell> 15 </md-table-row> 16 </md-table> 17 </div> 18</template> 19 20<script lang="ts"> 21import ChildForm from './ChildForm.vue' 22import Modal from './Modal.vue' 23import Vue from 'vue' 24 25type RefInterface = Vue & { 26 openModal(): void 27} 28 29export default Vue.extend({ 30 name: 'Parent', 31 components: { 32 Modal, 33 ChildForm, 34 }, 35 data() { 36 return { 37 products: [ 38 { 39 id: 1, 40 user: 'ユーザー1', 41 }, 42 { 43 id: 2, 44 user: 'ユーザー2', 45 }, 46 ], 47 } 48 }, 49 methods: { 50 onClickOpenModal() { 51 const child = this.$refs.child as RefInterface 52 child.openModal() 53 }, 54 }, 55}) 56</script>

【Modal.vue】

Vue

1<template> 2 <div> 3 <md-dialog :md-active.sync="active"> 4 <md-dialog-content> 5 <slot name="content" /> 6 </md-dialog-content> 7 </md-dialog> 8 </div> 9</template> 10 11<script lang="ts"> 12import Vue from 'vue' 13 14export default Vue.extend({ 15 name: 'Modal', 16 data() { 17 return { 18 active: false, 19 } 20 }, 21 methods: { 22 openModal() { 23 this.active = true 24 }, 25 }, 26}) 27</script>

【ChildModal.vue】

Vue

1<template> 2 <div> 3 {{ itemId }} ←IDを表示するも常に『2』のIDが表示されてしまう 4 </div> 5</template> 6 7<script lang="ts"> 8import Vue from 'vue' 9 10export default Vue.extend({ 11 name: 'ChildForm', 12 props: { 13 itemId: { 14 type: Number, 15 default: null, 16 }, 17 }, 18}) 19</script>

試したこと

Modalコンポーネント側でボタンを設置

【Modal.vue】

Vue

1<template> 2 <div> 3 <md-dialog :md-active.sync="active"> 4 <md-dialog-content> 5 <slot name="content" /> 6 </md-dialog-content> 7 </md-dialog> 8 <button @click="openModal">ボタン</button> 9 </div> 10</template>

↑のようなコードにした所、IDはデータに応じて表示されましたが、ボタンも今後種類が増えてCSS等変えていくと考えると、
0. ボタンもModalの外に設置する
0. Modalはあくまでモーダルビューを出すだけで、モーダル表示をさせたい要素をラッピングするだけの役割

で実装出来ればと考えているのですが、うまくいきませんでした。

ご教示いただきたいこと

テーブルコンポーネントで子コンポーネントに行ごとのIDを渡す方法

良い書き方が中々思い浮かばず詰まった末、質問させていただきました。
お手数をおかけし大変恐縮ですが、何卒宜しくお願い申し上げます。

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

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

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

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

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

plasticgrammer

2021/03/03 01:15

挙動について質問させてください。 onClickOpenModalで参照している this.$refs.child は配列になっていませんか? 複数行の場合、ref="child"が複数存在するものと思いますが、そのときには配列になってくれそうな気がしていますので確認まで。
im05ttbbh

2021/03/03 12:30

ご返信が遅くなってしまい誠に申し訳ございません。 おっしゃるように、this.$refs.childは複数アイテムが存在しますので、一つ一つユニークな識別子を与える必要がありました。 別の方のご回答のコードにはなってしまいますが、以下のようなコードでユニークな識別子を与えることで問題を解決することができました。 <Modal :ref="'child_'+ itemid"> ご指摘をいただき誠に有難うございました。
guest

回答1

0

ベストアンサー

モーダルが複数できるのはいいとして、それらのrefが全て"item"になっています。同名のrefが複数存在するときにthis.refsから参照するときに呼び出されるのは最後に宣言されたものになります。
つまり、id1のボタンを押したときにref="item"のモーダルを参照すると最後に宣言されているid2の行のモーダルが呼び出され表示されています。

以下のようにrefを動的に宣言してあげれば意図した挙動になるかと思います。
コードは殴り書きで書いてるので動くかは保証出来ないですが、イメージとしてはこんな感じです。

vue

1<md-table-cell md-label="アクション"> 2 <button @click="onClickOpenModal(item.id)">ボタン</button> 3 <Modal :ref="'child_'+ itemid"> ←親から子のメソッドにアクセスできるように実装 4 <template #content> 5 <ChildForm :item-id="item.id" /> 6 </template> 7 </Modal> 8</md-table-cell> 9 10 11onClickOpenModal(id) { 12 const child = this.$refs['child_'+ id] as RefInterface 13 child.openModal() 14},

投稿2021/03/03 04:28

zushi0905

総合スコア683

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

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

im05ttbbh

2021/03/03 12:34

ご返信が遅くなってしまい誠に申し訳ございません。 お教えいただいたコードでバッチリ動きました!! テーブルでアイテムが複数存在するので、refで参照する値はユニークな識別子が必要ですよね。 お教えいただきパッと解決はしましたが、しばらくハマっていた問題でしたので非常に助かりました。 また、自身でもthis.$refsをもう少し注意深くデバックすれば解決できたのではないかという反省もありますので、なぜ動かないのかをもう少し考えられるように精進したいと存じます。 この度は誠に有難うございました。心より感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問