You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js日程表项目v-for循环内模态框无法绑定对应列日期的问题求助

Fix: Modal Always Shows Last Date in Vue Schedule App

Hey there! Let's get this modal issue sorted out for your Vue schedule app.

The Root Cause

Your problem comes down to using a single modalToggled boolean to control all your modals. When you click any "+" button, modalToggled flips to true, which renders every <modal-component> in your v-for loop. Since all modals use position: fixed, the last one in the DOM stack ends up on top—so you always see the final date in your dayArr.

The Best Fix: Single Global Modal

Instead of rendering a modal for every column (which is inefficient), we'll use one single modal and track the date we want to display when the button is clicked. Here's how to adjust your code:

Updated App.vue

<template>
  <div>
    <table class='dataFrame'>
      <thead>
        <tr>
          <th v-for="date in dayArr" :key="date"> {{date}} </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="index in [1,2,3]" :key="index">
          <td v-for="(_, itemIndex) in dayArr" :key="itemIndex"> Dummy content </td>
        </tr>
        <tr>
          <td v-for="date in dayArr" :key="date">
            <!-- Pass the current date to the click handler -->
            <button @click="openModal(date)">+</button>
          </td>
        </tr>
      </tbody>
    </table>
    <div class="buttonSection">
      <button @click="currentOffset --" class="back" v-show="currentOffset >= -7">forward</button>
      <button @click="currentOffset ++" class="forward" v-show="currentOffset <= 7">backward</button>
    </div>

    <!-- Single global modal, moved outside the v-for loop -->
    <modal-component @changevisibility="closeModal" v-if="modalToggled">
      <p>{{ currentModalDate }}</p>
    </modal-component>
  </div>
</template>

<script>
import modalComponent from './components/modal.vue'
export default {
  data() {
    return {
      currentOffset: 0,
      modalToggled: false,
      currentModalDate: '', // Track the date to show in the modal
      dayArr: []
    }
  },
  methods: {
    openModal(date) {
      this.currentModalDate = date; // Set the date for the modal
      this.modalToggled = true; // Show the modal
    },
    closeModal() {
      this.modalToggled = false; // Hide the modal
    },
    getDatesArray() {
      let date = new Date();
      date.setDate(date.getDate() + this.currentOffset);
      let dayArr = [];
      for (let i = 0; i < 7; i++) {
        let customDateArray = new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'short', year: 'numeric', hour: 'numeric', minute: 'numeric' }).formatToParts(date)
        let dateParts = {}
        customDateArray.map(({type, value}) => {
          dateParts[type] = value
        })
        dayArr.push(`${dateParts.day}/${date.getMonth()+1}/${dateParts.year.slice(-2)}`)
        date.setDate(date.getDate() + 1);
      }
      this.dayArr = dayArr
    }
  },
  mounted () {
    this.getDatesArray()
  },
  watch: {
    currentOffset () {
      this.getDatesArray()
    }
  },
  name: 'App',
  components: {
    modalComponent
  }
}
</script>

<style>
#app {
  display: flexbox;
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50
}
.dataFrame {
  border: 2px solid;
  width: 100%;
  border-color: #2c3e50;
}
.buttonSection {
  margin-top: 1rem;
  width: 100%;
  max-height: 100%;
}
.back {
  float: left;
}
.forward {
  float: right;
}
</style>

modal.vue Stays the Same

Your existing modal component doesn't need any changes—it still emits the close event correctly.

Why This Works

  • We now have only one modal in the DOM, which is way more efficient than rendering seven.
  • When you click a "+" button, we first set currentModalDate to the date of that column, then show the modal.
  • Closing the modal just hides it, and we're ready to set a new date next time a button is clicked.

Alternative: Per-Column Modal States

If you really need a modal per column (not recommended for performance), you could track visibility with an object instead of a single boolean:

  1. Add modalStates: {} to your data
  2. In getDatesArray, initialize each date's state to false: this.modalStates = Object.fromEntries(this.dayArr.map(date => [date, false]))
  3. Update the button click to @click="modalStates[date] = true"
  4. Change the modal's v-if to v-if="modalStates[date]"

But again, the single global modal is cleaner and more efficient for your use case.

内容的提问来源于stack exchange,提问作者JoshJohnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 01:42:43