3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vuetifyでfor文の中にモーダル(v-dialog)を実装する方法

Last updated at Posted at 2023-05-03

なぜ書いた?

単純にモーダルをfor文の中に入れたら、常に最後の繰り返しの値を使ってmodalを開かれてしまい、繰り返しのモーダルごとで別々のinputの値を準備できず苦しんだため、自分以外にもそういう方がいたとき何かの参考になればと思って書きました。

結論(ソースコード)

for文を反映したモーダルの実装コード(vue3)
<script setup>
import { reactive, ref } from "vue";

const new_plans = reactive([
  { number: 0, bool: true },
  { number: 1, bool: false },
  { number: 2, bool: true },
]);

const dialog = ref(false);
let new_plan_for_dialog = ref(null);

const onClickBtn = (new_plan) => {
  new_plan_for_dialog.value = new_plan; //dialogの変数に要素を渡している
  dialog.value = true;
};
</script>

<template>
  <div v-for="(new_plan, index) in new_plans" :key="index">
    <v-btn @click.stop="onClickBtn(new_plan)"
      >ボタン{{ index }}</v-btn
    >
  </div>

  <v-dialog v-model="dialog" width="auto" activator>
    <v-card>
      <v-card-title>プランの設定・編集 </v-card-title>
      <v-card-text>
        Check
        <v-checkbox
          v-model="new_plan_for_dialog.bool"
          :label="`number${new_plan_for_dialog.number}は${new_plan_for_dialog.bool}`"
        ></v-checkbox>
      </v-card-text>
      <v-card-actions>
        <v-btn color="primary" block @click="dialog = false"
          >Close Dialog</v-btn
        >
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

※成功している画面の様子(ボタンごとに該当しているモーダルが表示されているのが見て取れます)
image.png
image.png

解説

上記のロジックはモーダルをfor文の個数分準備するのではなく、変数箇所だけ入れ替えて表示できるようになっています。

こうすることでコンパイル後のファイルのサイズ(DOMのサイズ)を小さくしつつ、inputしたい値はしっかり変数に格納できる最も効率の良い記述となっています。

参考にさせていただいた記事

余談(失敗したソースコード)

ちなみに筆者は下記のようなソースコードを書いて動かず苦しみました。(参考にしてうまく使いこなせなかった公式リファレンスのリンク

うまくいかなかったソースコード(参考)
<script setup>
import { reactive, ref } from "vue";

const new_plans = reactive([
  { number: 0, bool: true },
  { number: 1, bool: false },
  { number: 2, bool: true },
]);
const dialog = ref(false);
</script>
<template>
  <Default active-menu="accepted_authority_parents">
    <div v-for="(new_plan, index) in new_plans" :key="index">
    <!-- (失敗箇所ここから)※ダイアログをforと同じ個数準備してそれぞれ表示させようとしている -->
      <v-dialog v-model="dialog" width="auto">
        <template v-slot:activator="{ props }">
          <v-btn v-bind="props">ボタン{{ index }}</v-btn>
        </template>
        <v-card>
          <v-card-title>プランの設定・編集 </v-card-title>
          <v-card-text>
            Check
            <v-checkbox
              v-model="new_plan.bool"
              :label="`number${new_plan.number}は${new_plan.bool}`"
            ></v-checkbox>
          </v-card-text>
          <v-card-actions>
            <v-btn color="primary" block @click="dialog = false"
              >Close Dialog</v-btn
            >
          </v-card-actions>
        </v-card>
      </v-dialog>
    <!-- (失敗箇所ここまで) -->
    </div>
  </Default>
</template>

※ボタン0を押してもボタン2のモーダル(一番最後の繰り返しのモーダル)が出てしまう様子
image.png

こちらはおそらくactivator="{ props }"がうまく使えておらず、モーダルを使う指定の変数がわからないから最後のnew_planを使われているのではないかと思われます。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?