v-for inside v-for 在onclick事件中显示数据
v-for inside v-for displaying data in onclick event
大家好我有对象数组,在每个对象里面我也有对象数组..
我在 v-for 里面做了 v-for 来显示数据
起初我想让每一行显示父数组和 onClick 事件的每个子项的第一个元素的数据,我只想更改特定行中的数据。
infos: [{
name: 'name1',
infosName: [{
place: 'place.1.1',
surface: '100'
},
{
place: 'place.1.2',
surface: '200'
}
]
},
{
name: 'name2',
infosName: [{
place: 'place.2.1',
surface: '300'
},
{
place: 'place.2.2',
surface: '400'
}
]
}
]
我创建了一个显示数据的方法并获得了参数两个索引
这是一个 jsfiddle 来了解更多问题
谢谢
有几个问题需要解决,但您的思路是正确的。
最重要的是,您不仅需要存储一个 "myIndex",还需要为每一行 "myIndex" 存储一个单独的 "myIndex"
这就是问题的根本原因。
让我改一下你的问题?
我相信你希望有四个按钮。顶部的两个按钮在两个选项之间进行选择。
完全分开,底部的两个按钮在两个选项之间进行选择。
如果你把最上面的两个按钮叫做“问题1,选项A”和“问题1,选项B”,读者会更容易理解你的意图。然后是最下面的两个“问题 2...”。然后他们就会明白为什么当您单击其中一个按钮时,您只想影响该行的 table 的输出。
避免使用通用术语,例如 "index" 和 "i"
这些会使人们不必要地难以理解您的意图。最好使用具体名词,在本例中为“问题”或“答案”,并在表示索引时在其前面加上“i”,例如“iQuestion”表示问题的索引,“question”表示问题本身.
您似乎只有一个函数 "getInfos" 可以同时获取和设置信息
这是个大问题。你应该把这两个功能分开。
当您点击时,您想要 运行 一个“设置”功能,它会更新您的索引。
当您只是简单地显示时,您可以访问“get”函数,它不会改变任何东西。
您需要为每一行存储一个索引
用我的术语来说,你需要存储你对每个问题的答案的索引。
所以不是 this.myIndex 从 0 开始,而是从 [0,0] 开始。这两个值中的每一个都可以单独更新,允许程序更新一行(即一个问题)的答案,同时保持另一行不变。
我已将此变量重命名为 this.myAnswer 以便于理解。
this.$在写入您希望 Vue 做出反应的数组时设置
我最初写的“setAnswer”函数如下:
this.myAnswer[iQuestion]=iAnswer
但是,我发现屏幕显示没有更新。这是 Vue 中的一个常见问题,当您更新的不是 data()
中列出的主要 属性,而是 属性.
的数组元素时
这是因为 Vue 不跟踪数组元素的更新,只跟踪数组本身。因此,如果您要重新分配整个数组,Vue 会注意到。
解决方法是明确告诉 Vue 您正在更新需要响应的内容。然后 Vue 将在屏幕上更新它。
为此,请将您的分配从以下格式更改为:
this.array[index] = value
对此
this.$set(this.array, index, value)
Vue 提供了这个函数 this.$set
,它执行你的正常 this.array[index] = value
并且 告诉 Vue 进行屏幕更新。
如何应对失踪"infosName"
回复你在评论中的问题。你有一个方便的地方来解决这个问题:你的 getAnswer()
函数。
由此变化:
getAnswer(iQuestion,iAnswer){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
对此:
getAnswer(iQuestion,iAnswer){
if (this.infos.length>iQuestion &&
this.infos[iQuestion].infosName &&
this.infos[iQuestion].infosName.length>iAnswer
){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
else return {
name : "",
surface: ""
}
}
解决方案
html:
<div id="app">
<div v-for="(question,iQuestion) in infos">
<div class="row d-flex">
<span style="margin-right:10px" v-for="(answer,iAnswer) in question.infosName" class="badge badge-primary" @click="setAnswer(iQuestion,iAnswer)"><i class="fa fa-eye" style="margin-right:10px;cursor: pointer"></i>{{ answer.place }}</span> </div>
<div class="row">
<p>Name : {{ getAnswer(iQuestion,myAnswer[iQuestion]).name }} </p>
<p>Surface : {{ getAnswer(iQuestion,myAnswer[iQuestion]).surface }}</p>
</div>
</div>
</div>
JS:
new Vue({
el :'#app',
data : function(){
return {
myAnswer : [0,0],
infos : [
{
name : 'name1',
infosName : [
{
place : 'Question 1, Option A',
surface : '100'
},
{
place : 'Question 2, Option B',
surface : '200'
}
]
},
{
name : 'name2',
infosName : [
{
place : 'Question 2, Option A',
surface : '300'
},
{
place : 'Question 2, Option B',
surface : '400'
}
]
}
]
}
},
methods:{
setAnswer(iQuestion,iAnswer){
this.$set(this.myAnswer,iQuestion,iAnswer)
},
getAnswer(iQuestion,iAnswer){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
}
}
})
大家好我有对象数组,在每个对象里面我也有对象数组.. 我在 v-for 里面做了 v-for 来显示数据 起初我想让每一行显示父数组和 onClick 事件的每个子项的第一个元素的数据,我只想更改特定行中的数据。
infos: [{
name: 'name1',
infosName: [{
place: 'place.1.1',
surface: '100'
},
{
place: 'place.1.2',
surface: '200'
}
]
},
{
name: 'name2',
infosName: [{
place: 'place.2.1',
surface: '300'
},
{
place: 'place.2.2',
surface: '400'
}
]
}
]
我创建了一个显示数据的方法并获得了参数两个索引 这是一个 jsfiddle 来了解更多问题
谢谢
有几个问题需要解决,但您的思路是正确的。
最重要的是,您不仅需要存储一个 "myIndex",还需要为每一行 "myIndex" 存储一个单独的 "myIndex"
这就是问题的根本原因。
让我改一下你的问题?
我相信你希望有四个按钮。顶部的两个按钮在两个选项之间进行选择。
完全分开,底部的两个按钮在两个选项之间进行选择。
如果你把最上面的两个按钮叫做“问题1,选项A”和“问题1,选项B”,读者会更容易理解你的意图。然后是最下面的两个“问题 2...”。然后他们就会明白为什么当您单击其中一个按钮时,您只想影响该行的 table 的输出。
避免使用通用术语,例如 "index" 和 "i"
这些会使人们不必要地难以理解您的意图。最好使用具体名词,在本例中为“问题”或“答案”,并在表示索引时在其前面加上“i”,例如“iQuestion”表示问题的索引,“question”表示问题本身.
您似乎只有一个函数 "getInfos" 可以同时获取和设置信息
这是个大问题。你应该把这两个功能分开。
当您点击时,您想要 运行 一个“设置”功能,它会更新您的索引。
当您只是简单地显示时,您可以访问“get”函数,它不会改变任何东西。
您需要为每一行存储一个索引
用我的术语来说,你需要存储你对每个问题的答案的索引。
所以不是 this.myIndex 从 0 开始,而是从 [0,0] 开始。这两个值中的每一个都可以单独更新,允许程序更新一行(即一个问题)的答案,同时保持另一行不变。
我已将此变量重命名为 this.myAnswer 以便于理解。
this.$在写入您希望 Vue 做出反应的数组时设置
我最初写的“setAnswer”函数如下:
this.myAnswer[iQuestion]=iAnswer
但是,我发现屏幕显示没有更新。这是 Vue 中的一个常见问题,当您更新的不是 data()
中列出的主要 属性,而是 属性.
这是因为 Vue 不跟踪数组元素的更新,只跟踪数组本身。因此,如果您要重新分配整个数组,Vue 会注意到。
解决方法是明确告诉 Vue 您正在更新需要响应的内容。然后 Vue 将在屏幕上更新它。
为此,请将您的分配从以下格式更改为:
this.array[index] = value
对此
this.$set(this.array, index, value)
Vue 提供了这个函数 this.$set
,它执行你的正常 this.array[index] = value
并且 告诉 Vue 进行屏幕更新。
如何应对失踪"infosName"
回复你在评论中的问题。你有一个方便的地方来解决这个问题:你的 getAnswer()
函数。
由此变化:
getAnswer(iQuestion,iAnswer){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
对此:
getAnswer(iQuestion,iAnswer){
if (this.infos.length>iQuestion &&
this.infos[iQuestion].infosName &&
this.infos[iQuestion].infosName.length>iAnswer
){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
else return {
name : "",
surface: ""
} }
解决方案
html:
<div id="app">
<div v-for="(question,iQuestion) in infos">
<div class="row d-flex">
<span style="margin-right:10px" v-for="(answer,iAnswer) in question.infosName" class="badge badge-primary" @click="setAnswer(iQuestion,iAnswer)"><i class="fa fa-eye" style="margin-right:10px;cursor: pointer"></i>{{ answer.place }}</span> </div>
<div class="row">
<p>Name : {{ getAnswer(iQuestion,myAnswer[iQuestion]).name }} </p>
<p>Surface : {{ getAnswer(iQuestion,myAnswer[iQuestion]).surface }}</p>
</div>
</div>
</div>
JS:
new Vue({
el :'#app',
data : function(){
return {
myAnswer : [0,0],
infos : [
{
name : 'name1',
infosName : [
{
place : 'Question 1, Option A',
surface : '100'
},
{
place : 'Question 2, Option B',
surface : '200'
}
]
},
{
name : 'name2',
infosName : [
{
place : 'Question 2, Option A',
surface : '300'
},
{
place : 'Question 2, Option B',
surface : '400'
}
]
}
]
}
},
methods:{
setAnswer(iQuestion,iAnswer){
this.$set(this.myAnswer,iQuestion,iAnswer)
},
getAnswer(iQuestion,iAnswer){
return {
'name' : this.infos[iQuestion].infosName[iAnswer].place,
'surface' : this.infos[iQuestion].infosName[iAnswer].surface
}
}
}
})