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 来了解更多问题

谢谢

https://jsfiddle.net/f0ehwacm/2

有几个问题需要解决,但您的思路是正确的。

最重要的是,您不仅需要存储一个 "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
      }
    }
  }
})