VueJS手风琴表 - 基于实时系统的约束

时间:2017-06-14 17:55:00

标签: jquery vue.js vue-component

此问题从此处发布:

VueJS Accordion Table - Appears outside of the table

@Bert Evans提供的答案很好,但是,在我正在开发的系统中,存在一些不能使其工作的约束。

主要的限制是我正在开发一个基于实时的系统,它利用了store,所以当用户编辑某些内容时,会触发一个动作来拉动所有来自ajax调用的数据。提供的解决方案使用contentVisible,虽然我可以在调用操作时对其进行映射,但主要问题是,无论何时调用操作,contentVisible都设置为false默认情况下导致手风琴关闭。

我曾尝试创建数据副本,但这还不够。基本上,我需要一种方法来检测某人是否已点击某一行,然后在其下方显示手风琴。

有什么建议吗?

console.clear()

var vm = new Vue({
  el: '#vue-instance',
  data: {
    testing: [{
        id: 1,
        name: "Customer 1",
        contentVisible: false

      },
      {
        id: 2,
        name: "Customer 1",
        contentVisible: false

      },
      {
        id: 3,
        name: "Customer 3",
        contentVisible: false

      },
    ],
    columns: ["id", "name"]
  },

  mounted() {
    console.log(this.testing);
  },

  methods: {
    showRow(data) {
      this.contentVisible = !this.contentVisible;

    }

  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="vue-instance">
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th v-for="column in columns">
          {{column}}
        </th>
      </tr>
    </thead>

    <tbody>
      <template v-for="row in testing">
        <tr @click="row.contentVisible = !row.contentVisible">
           <td>{{row.id}}</td>
           <td>{{row.name}}</td>
         </tr>
         <tr v-if="row.contentVisible">
           <td :colspan="columns.length" >
             <div class="accordian-body">
               afasfafs
             </div>
           </td>
         </tr>
      </template>
    </tbody>
  </table>
</div>

1 个答案:

答案 0 :(得分:2)

我将提供一个稍微简化的Bert Evans答案(自删除后),其中扩展状态与数据分开跟踪。我只是使用字典而不是数组来跟踪哪些是打开的id,因为它更容易检查成员身份和删除。

console.clear()

const testing = [{
    id: 1,
    name: "Customer 1",
  },
  {
    id: 2,
    name: "Customer 2",
  },
  {
    id: 3,
    name: "Customer 3",
  },
]

var vm = new Vue({
  el: '#vue-instance',
  data: {
    testing,
    expanded: {},
    columns: ["id", "name"],
    replacedCounter: 0
  },
  mounted() {
    setInterval(() => {
      this.testing = testing
      this.replacedCounter++
    }, 3000)
  },
  methods: {
    expand(id) {
      if (id in this.expanded)
        this.$delete(this.expanded, id);
      else
        this.$set(this.expanded, id, true);
    }
  }
});
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="vue-instance">
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th v-for="column in columns">
          {{column}}
        </th>
      </tr>
    </thead>

    <tbody>
      <template v-for="row in combined">
        <tr @click="expand(row.id)">
           <td>{{row.id}}</td>
           <td>{{row.name}}</td>
         </tr>
         <tr v-if="row.id in expanded">
           <td :colspan="columns.length" >
             <div class="accordian-body">
               afasfafs
             </div>
           </td>
         </tr>
      </template>
    </tbody>
  </table>
  Testing: {{testing}} <br /> Expanded: {{expanded}} <br /> Replaced: {{replacedCounter}}
</div>