javascript - v-for 中每个组件的唯一内容
问题描述
程序说明:我正在用 Vue.js 制作一个简单的时间表程序。该页面有一个“日历”(一个包含 7 列的表格,其中每一列对应一个特定日期)和每个日历列底部的按钮。单击按钮时,模式应弹出其正文内容中的特定日期。模式的正文内容中的日期应与放置按钮的列标题中的日期相同。forward
单击或backward
按钮也可以更改日期。单击forward
所有日期时,将向前移动一天。如果backward
所有日期向后移动一天。
程序的方法:我有一个App.vue
用于 modal 的父组件和一个子组件modal.vue
。在父组件中,作为属性之一,我有一个数组dateArr
,其中包含以下格式的 7 个不同日期:['9/11/21', '9/12/21', ..., '15/11/21']
. 正在调用App.vue
挂载方法,该方法用日期填充属性。单击并正在更改并且正在触发方法。表的第一行包含日期,因此我创建它并遍历每个getDatesArray
dateArr
backward
forward
currentOffset
getDatesArray
v-for
date
dateArr
. 表的主体由每列 3 行组成。每列的最后一行包含一个唯一的按钮和一个模式。在最后一行中,我想将每个组件绑定到特定日期,所以我再次遍历每个date
in dateArr
。模态组件中有一个插槽,我在其中放置了 unique date
from dateArr
。单击按钮时,模态的可见性随change
方法而变化。
问题:一切正常,但是,无论我单击什么按钮,date
模态组件的内容 ( ) 都保持不变:15/11/21
,这是数组的最后一个元素。该程序的目的是date
在每个模态组件内拥有唯一的内容 (),核心属性 ( dateArr
) 是动态的。我已经尝试对这个问题实施不同的解决方案,但没有一个有用。我将非常感谢任何帮助!
App.vue
:
<template>
<table class = 'dataFrame'>
<thead>
<tr>
<th v-for="item in dayArr" :key="item.id">
{{item}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="index in [1,2,3]" :key="index">
<td v-for="item_index in dayArr.length" :key="item_index">
Dummy content
</td>
</tr>
<tr>
<td v-for="date in dayArr" :key="date.id">
<button @click="change">+</button>
<modal-component @changevisibility="change" v-if="modalToggled">
<p>{{ date }}</p>
</modal-component>
</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>
</template>
<script>
import basecard from './components/card.vue'
import navbarComponent from './components/menu.vue'
import modalComponent from './components/modal.vue'
export default {
data() {
return {
currentOffset: 0,
modalToggled : false,
dayArr: []
}
},
methods: {
change() {
this.modalToggled = !this.modalToggled
},
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
:
<template>
<div class="modal">
<div class="modal-content">
<slot></slot>
<button @click="changeVisibilityFromComponent">
<span class="close">Close ×</span>
</button>
</div>
</div>
</template>
<script>
export default {
name: 'modalComponent',
methods: {
changeVisibilityFromComponent () {
this.$emit('changevisibility')
},
}
}
</script>
<style scoped>
.modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>
解决方案
我想到的第一件事是传递一个索引来改变函数,从而计算一些独立于 v-for 循环的值:
<td v-for="(date, index) in dayArr" :key="date.id">
<!-- pass index to change method -->
<button @click="change(index)" :id="index">+</button>
<modal-component @changevisibility="change(index)" v-if="modalToggled">
<!-- to slot pass the new variable -->
<!-- remember to add it to data() with some init value like null -->
<p>{{ currentDate }}</p>
</modal-component>
</td>
...
methods: {
change(index) {
// set currentDate value each time change method is being run
this.currentDate = this.dayArr[index];
this.modalToggled = !this.modalToggled
},
...
}
您遇到问题的原因是 v-for 呈现项目列表并以与以下代码相同的方式设置变量:
let x = 0;
for (i = 0; i < 10; i++) {
x = i;
}
console.log(x); // this will always console out x = 9
相反,事件处理(如@click
)创建一个监听 DOM 事件并在每次触发事件时运行一个方法的指令。至少我是这么理解的……</p>
推荐阅读
- mongodb - 将 mongodb 集合导出到 csv
- r - 如何解决这个错误:错误:美学必须是长度1或与数据相同(1):标签,x,y,颜色和组
- android - Android 12 模拟器中的 Google Chrome 浏览器不加载任何网页(互联网正在运行!)
- python - 在 SchemaRegistryClient Confluent Kafka 中禁用证书验证
- javascript - 第一次点击路由按钮后Nextjs页面刷新
- python - Django如何检查ModelField中的布尔值是否为真
- swiftui - HStack 行为中带有弹出框的 SwiftUI 多个按钮
- sql - 如何根据命令的数量确定每天要复制多少数据?
- node.js - Sequelize 上的行数错误?
- android - JetPack Compose - 从视图中删除额外的填充