🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
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

解決済

2回答

3307閲覧

Vue.jsでモーダルの状態を親コンポーネントで動的に管理したい

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/05 14:20

実現したいこと

Vue.jsでモーダルの状態を親コンポーネントで動的に管理したい

状況

  1. Vue Materialのテーブルコンポーネントを使用
  2. Modalコンポーネントを作成し、ラップした要素をモーダル表示できるように実装(今回はFormコンポーネントをラッピング)
  3. Parent.vuemodalStateを定義し、Parent.vueで子であるモーダルの状態を管理

↑のような状況で親であるParent.vueでモーダルの状態を保持し、ボタンを押すことで、子のモーダルが表示されるようにしたい。

問題の箇所

Parent.vueで定義したモーダルの状態を子であるModal.vueに渡すと、全てのモーダルが表示されてしまう。

【Modal.vue】

Vue

1<md-dialog :md-active.sync="modalState"> ←全てのモーダルがtrueになってしまう 2 <md-dialog-content> 3 <slot name="content" /> 4 {{ itemId }} 5 </md-dialog-content> 6</md-dialog>

問題箇所のアニメーション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="modalStateTrue">モーダル表示</button> 9 <Modal :item-id="item.id" :modal-state="modalState"> ←モーダルの状態をpropsで渡す 10 <template #content> 11 <Form :item-id="item.id" /> ←modalStateがtrueならフォームを表示させる 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 Form from './components/Form.vue' 22import Modal from './components/Modal.vue' 23import Vue from 'vue' 24 25export default Vue.extend({ 26 name: 'Table', 27 components: { 28 Modal, 29 Form, 30 }, 31 data() { 32 return { 33 products: [ 34 { 35 id: 1, 36 user: 'ユーザー1', 37 }, 38 { 39 id: 2, 40 user: 'ユーザー2', 41 }, 42 ], 43 modalState: false, 44 } 45 }, 46 methods: { 47 modalStateTrue() { 48 this.modalState = true 49 }, 50 }, 51}) 52</script>

【Modal.vue】

Vue

1<template> 2 <div> 3 <md-dialog :md-active.sync="modalState"> ←全てのモーダルがtrueになってしまう 4 <md-dialog-content> 5 <slot name="content" /> 6 {{ itemId }} 7 </md-dialog-content> 8 </md-dialog> 9 </div> 10</template> 11 12<script> 13import Vue from 'vue' 14 15export default Vue.extend({ 16 name: 'Modal', 17 props: { 18 modalState: { 19 type: Boolean, 20 }, 21 itemId: { 22 type: Number, 23 default: null, 24 }, 25 }, 26}) 27</script>

【Form.vue】

Vue

1<template> 2 <div id="itemId"> 3 <input /> 4 </div> 5</template> 6 7<script lang="ts"> 8import Vue from 'vue' 9 10export default Vue.extend({ 11 name: 'Form', 12 props: { 13 itemId: { 14 type: Number, 15 required: true, 16 }, 17 }, 18}) 19</script>

試したこと

親から子であるModalに対してユニークなIDを渡し、DOM要素のIDとして追加する

【Parent.vue】

Vue

1<button @click="modalStateTrue(item.id)">モーダル表示</button> 2<Modal :item-id="item.id" :modal-state="modalState.state"> ←propsのitemIdを使用 3 <template #content> 4 <Form :item-id="item.id" /> 5 </template> 6</Modal>

【Modal.vue】

Vue

1<md-dialog :id="itemId" :md-active.sync="modalState"> ←要素にユニークなIDを与える 2 <md-dialog-content> 3 <slot name="content" /> 4 {{ itemId }} 5 </md-dialog-content> 6</md-dialog>

↑のようなコードにした所、IDはモーダルアイテムごとに渡っていることを確認できましたが、
全てのモーダルが一度で表示される状態は変わりませんでした。

ご教示いただきたいこと

Vue.jsでモーダルの状態を親コンポーネントで管理する方法

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

【追伸】
↓以前似たような質問をしておりますが、そちらでは親から$refを使用して子のメソッドを操作する質問でしたが、今回は親で状態管理の質問になります。

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

応用が効かずに誠に恥ずかしい限りなのですが、ご指導賜りますようお願い申し上げます。

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

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

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

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

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

guest

回答2

0

itemオブジェクトにshow_modal default/falseみたいなフラグを足してはどうでしょうか。
dataに入れる前にフラグを追加しておくと良いです。

投稿2021/03/06 10:01

mikkame

総合スコア5036

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

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

im05ttbbh

2021/03/07 06:08

返信が遅くなり申し訳ございません。 方法をご教示いただき誠にありがとうございました! 自己解決方法にも記載しましたが、ユニークなidを与えることで解決することができました。 ヒントをいただけたおかげで解決できましたので、重ねて御礼申し上げます。
guest

0

自己解決

modalStateの定義をオブジェクトにし、テーブルごとにユニークなmodalStateを作成することにより解決できました。なお、Modal.vueは使わなくなったので削除しています。

【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="$set(modalState, item.id, true)">モーダル表示</button> ←変更箇所 9 <md-dialog :md-active.sync="modalState[item.id]"> ←変更箇所 10 <Form :item-id="item.id" /> 11 </md-dialog> 12 </md-table-cell> 13 </md-table-row> 14 </md-table> 15 </div> 16</template> 17 18<script lang="ts"> 19 20export default Vue.extend({ 21 ---略--- 22 23 data() { 24 return { 25 modalState: {}, 26 } 27 }, 28 29 ---略--- 30}) 31</script>

投稿2021/03/07 06:07

im05ttbbh

総合スコア18

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問