为什么子表(toggle-table)每当点击父表的行时就会重复?

问题描述 投票:0回答:1

我试图制作一个包含国家各州GDP的表,当有人点击州行时,就会出现子表(地区GDP表)。当任何人点击国家行时,子表(地区GDP表)就会出现。它工作正常,但子表在重复。我做了一个toggle函数来控制子表的hideshow。解决这个问题将被感激。

运行Snippet来正确理解这个问题。

  var app = new Vue({
  el: "#app",
  data(){
    return {
    opened:[],
    stateGDP: [
        { State: "Rajasthan", "1999-00": "2547", "2000-01": "3679",Id:"23" },
        { State: "Orissa", "1999-00": "38714", "2000-01": "38814",Id:"24" }
      ],
      DistrictGDP: [
        {
          State: "Rajasthan",
          District: "Jaipur",
          "1999-00": "2547",
          "2000-01": "3679",
          Id:"23"
        },
        {
          State: "Rajasthan",
          District: "Jodhpur",
          "1999-00": "2557",
          "2000-01": "3639",
          Id:"23"
        },
        {
          State: "Orissa",
          District: "Bhubaneswar",
          "1999-00": "1983",
          "2000-01": "2068",
          Id:"24"
        },
        {
          State: "Orissa",
          District: "Puri",
          "1999-00": "1923",
          "2000-01": "2008",
          Id:"24"
        }
      ]
      }
    },
  methods:{
    toggle:function(Id) {
    const index = this.opened.indexOf(Id);
    if (index > -1) {
      this.opened.splice(index, 1)
    } else {
      this.opened.push(Id)
    }
 }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
        <div class="table">
          <table class="table-fill">
            <thead>
            <tr>
    <th class="text-center">State/UT</th>
    <th class="text-center">1999-00</th>
    <th class="text-center">2000-01</th>
</tr>
</thead>
  <template v-for="row in stateGDP">
    <tr @click="toggle(row.Id)" :class="{ opened: opened.includes(row.Id) }">
      <td>{{ row.State }}</td>
      <td>{{ row['1999-00'] }}</td>
      <td>{{ row['2000-01'] }}</td>
    </tr>
    <template v-for="(xy, indexStop) in DistrictGDP" v-if="opened.includes(row.Id) && row.Id==xy.Id">
    <thead>
    <tr>
<th class="text-center">District</th>
<th class="text-center">1999-00</th>
<th class="text-center">2000-01</th>
</tr>
</thead>
    <template v-for="xy in DistrictGDP" v-if="opened.includes(row.Id) && row.Id==xy.Id">
   <tr>
     <td colspan="1">{{xy.District}}</td>
     <td colspan="1">{{xy['1999-00']}}</td>
     <td colspan="1">{{xy['2000-01']}}</td>
   </tr></template>
   </template>
</template>
</table>
</div>
</div>
javascript html vue.js
1个回答
3
投票

  var app = new Vue({
  el: "#app",
  data(){
    return {
    opened:[],
    stateGDP: [
        { State: "Rajasthan", "1999-00": "2547", "2000-01": "3679",Id:"23" },
        { State: "Orissa", "1999-00": "38714", "2000-01": "38814",Id:"24" }
      ],
      DistrictGDP: [
        {
          State: "Rajasthan",
          District: "Jaipur",
          "1999-00": "2547",
          "2000-01": "3679",
          Id:"23"
        },
        {
          State: "Rajasthan",
          District: "Jodhpur",
          "1999-00": "2557",
          "2000-01": "3639",
          Id:"23"
        },
        {
          State: "Orissa",
          District: "Bhubaneswar",
          "1999-00": "1983",
          "2000-01": "2068",
          Id:"24"
        },
        {
          State: "Orissa",
          District: "Puri",
          "1999-00": "1923",
          "2000-01": "2008",
          Id:"24"
        }
      ]
      }
    },
  methods:{
    toggle:function(Id) {
    const index = this.opened.indexOf(Id);
    if (index > -1) {
      this.opened.splice(index, 1)
    } else {
      this.opened.push(Id)
    }

 },
    getRows(id) {
      return this.DistrictGDP.filter(district => district.Id === id);
    }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">. 
</script>
<div id="app">
  <div class="table">
    <table class="table-fill">
      <thead>
        <tr>
          <th class="text-center">State/UT</th>
          <th class="text-center">1999-00</th>
          <th class="text-center">2000-01</th>
        </tr>
      </thead>
      <template v-for="row in stateGDP" :class="{ opened: opened.includes(row.Id) }">
        <tr @click="toggle(row.Id)" style="background-color: #D3D3D3">
          <td>{{ row.State }}</td>
          <td>{{ row["1999-00"] }}</td>
          <td>{{ row["2000-01"] }}</td>
        </tr>
        <template
          v-if="opened.includes(row.Id)"
        >
          <thead>
            <tr>
              <th class="text-center">District</th>
              <th class="text-center">1999-00</th>
              <th class="text-center">2000-01</th>
            </tr>
          </thead>
        <tr v-for="(district, index) in getRows(row.Id)">
          <td colspan="1">{{district.District}}</td>
          <td colspan="1">{{district['1999-00']}}</td>
          <td colspan="1">{{district['2000-01']}}</td>
        </tr>
        </template>
      </template>
    </table>
  </div>
</div>

   

现在的解释是,为了得到你想在点击时显示的行,你正在做一个v-for循环,并重新创建表头和整个嵌套表的相同数量的DistrictGDP存在与stateGDP相同的Id(在这种情况下是两次)。

我去掉了那个v-for(整个代码中的第二个),为了渲染嵌套表的行,我增加了一个方法,getRows,这个方法根据row.Id过滤所需的行,这样一来,如果DistrictGDP中的id和stateGDP中的id相同,表就不需要比较了。

如果我说的不清楚,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.