0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vueでモーダルウインドウを作成

Posted at

スクリーンショット 2025-01-10 174906.jpg

モーダルウインドウの実装例

/src/views/SideBar.vue

<li>タグを右クリックすると現れるモーダルウインドウを実装

@contextmenu.prevent="handleRightClick(record, $event)"と書いて右クリックイベント実装

<template>
  <div>
    <label>サイドバー</label>
    <!-- リストの表示範囲を制限してスクロール可能にする -->
    <ul class="max-h-[calc(100dvh_-_50px)] overflow-y-auto space-y-2 bg-white shadow-md rounded-md custom-scrollbar">
      <li
        v-for="(record) in filteredRecords"
        :key="record.data_id"
        class="border-b border-gray-200 last:border-b-0 flex items-center cursor-pointer"
        @click="handleClick(record)"
        @contextmenu.prevent="handleRightClick(record, $event)"
      >
        <!-- 動的に画像パスをバインド -->
        <img :src="`./thumbnail/${record.img_path}`" alt="record image">
      </li>
    </ul>

    <!-- モーダルウィンドウ -->
    <div
      v-if="isModalVisible"
      class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
    >
      <div class="bg-white p-4 rounded shadow-md w-96">
        <h3 class="text-lg font-semibold mb-2">Record Details</h3>
        <p><strong>Data ID:</strong> {{ selectedRecord?.data_id }}</p>
        <p><strong>Image Path:</strong> {{ selectedRecord?.img_path }}</p>
        <button
          @click="closeModal"
          class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          Close
        </button>

        <button
          @click="OpenPic_btn"
          class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          画像を開く
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, reactive, computed, watch, onMounted, toRefs,getCurrentInstance } from 'vue';
import { useUserStore } from "../stores/userStore";

export default {
  name: "SideBar",
  setup() {
    const filteredRecords = ref([]);
    const userStore = useUserStore();
    const isModalVisible = ref(false); // モーダルの表示状態
    const selectedRecord = ref(null); // 選択されたレコード

    // フィルタリングロジック
    const updateFilteredRecords = () => {
      if (!userStore.records || !Array.isArray(userStore.records)) {
        filteredRecords.value = [];
        return;
      }
      filteredRecords.value = userStore.records;
    };

    // `userStore.records` の変更を監視
    watch(
      () => userStore.records,
      (newRecords, oldRecords) => {
        console.log("userStore.recordsが変更されました:", {
          newRecords,
          oldRecords,
        });
        updateFilteredRecords();
      },
      { deep: true, immediate: true }
    );

    // 左クリックイベントの処理
    const handleClick = (record) => {
      console.log("クリックされたレコード:", record);
      userStore.setSelectItem(record);
    };

    // 右クリックイベントの処理
    const handleRightClick = (record, event) => {
      console.log("右クリックされたレコード:", record);
      event.preventDefault(); // デフォルトのコンテキストメニューを防止
      selectedRecord.value = record; // 選択されたレコードを保存
      isModalVisible.value = true; // モーダルを表示
    };

    // 新しいタブでリンクを開く
    const OpenPic_btn = () => {
      if (selectedRecord.value && selectedRecord.value.img_path) {
        const link = `./images/${selectedRecord.value.img_path}`;
        window.open(link, "_blank"); // 新しいタブでリンクを開く
      }
      isModalVisible.value = false;
      selectedRecord.value = null;
    };

    // モーダルを閉じる
    const closeModal = () => {
      isModalVisible.value = false;
      selectedRecord.value = null;
    };

    const { proxy } = getCurrentInstance();
    const showSuccessToast = () => {
      if (!proxy || !proxy.$toast) {
        console.error("Toast instance is undefined. Ensure VueToast is properly registered.");
        return;
      }
      proxy.$toast.open({
        message: "操作が成功しました!",
        type: "success",
        duration: 5000,
      });
    };

    return {
      //----------------------------------//
      showSuccessToast,
      //---------------------------------//
      filteredRecords,
      userStore,
      handleClick,
      handleRightClick,
      isModalVisible,
      selectedRecord,
      closeModal,
      OpenPic_btn,
    };
  },
};
</script>

<style>
/* カスタムスクロールバーのデザイン */
.custom-scrollbar {
  scrollbar-width: thin;
  scrollbar-color: #888 #f0f0f0;
}
.custom-scrollbar::-webkit-scrollbar {
  width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: #888;
  border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background-color: #555;
}

/* モーダルスタイル */
.fixed {
  position: fixed;
}

.inset-0 {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.bg-opacity-50 {
  background-color: rgba(0, 0, 0, 0.5);
}

.z-50 {
  z-index: 50;
}

.flex {
  display: flex;
}

.items-center {
  align-items: center;
}

.justify-center {
  justify-content: center;
}

.shadow-md {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
</style>

モーダルウインドウ本体部分

    <!-- モーダルウィンドウ -->
    <div
      v-if="isModalVisible"
      class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
    >
      <div class="bg-white p-4 rounded shadow-md w-96">
        <h3 class="text-lg font-semibold mb-2">Record Details</h3>
        <p><strong>Data ID:</strong> {{ selectedRecord?.data_id }}</p>
        <p><strong>Image Path:</strong> {{ selectedRecord?.img_path }}</p>
        <button
          @click="closeModal"
          class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          Close
        </button>

        <button
          @click="OpenPic_btn"
          class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          画像を開く
        </button>
      </div>
    </div>
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?