根据来自 API 的响应显示多个引导 VueJS 表 [英] Displaying multiple bootstrap VueJS tables based on response from API

查看:24
本文介绍了根据来自 API 的响应显示多个引导 VueJS 表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 bootstrap-vue 表.目前,我的全部数据都在一张表中.假设此表中有 10 行,前 5 行的第一列包含值 A,而接下来的 5 行包含第一列的值 B.

我想要的是,不是有一个包含完整数据的单个表,我将这个表分开,这样在我的页面上就会出现两个表.第一个表将包含值为 A 的所有行,第二个表将包含值为 B 的所有行.实际上,我会有很多这样的唯一值,所以假设我有 10 个这样的值,我想要 10 个基于这些值的这样的单独表.这是可能的吗?

另一个想法可能是,如果以上不可能,我可以有可折叠的行吗?我不是在谈论 More Details 功能,而是当我点击 A 时,所有值为 A 的行都会出现在同一个表格,每个表格都作为表格中的一行出现.

我最初想拥有可以跨列的行(在 bootstrap Vue 表中分组行) 但不幸的是,bootstrap vue-js 表尚不支持.

解决方案

您可以通过使用将数组拆分为多个组的计算属性来实现此目的.

此计算属性将返回一个对象,其中包含一个键,该键将作为您分组的值,而该值将是一个包含该组中所有项目的数组.

/* 计算属性将返回的示例结构 */{一种: [],乙:[],C: []}

然后您可以使用 v-for 查看 groupedItems

中的每个键

<!--groupedItems 是计算属性,包含上面显示的结构.将为 `groupedItems` 属性中的每个类型/键创建一个新表.--><div v-for="(group, type) in groupedItems"><b-table :fields="fields";:items="group">


示例片段:

一个相当基本的例子,它只显示类型的标题和下面的表格.

/* 生成一些随机示例数据 */const 类型 = ['A', 'B', 'C']常量项 = [];for(让我= 0;我<15;我++){项目.推({类型:类型[i % 3],编号:我 + 1,随机:Math.random()})}新的 Vue({el: '#app',计算:{分组项目(){常量组 = {};this.items.forEach(item => {如果(组[项目.类型]){组[item.type].push(item);} 别的 {组[item.type] = [item];}});返回组;}},数据() {返回 {物品:物品,字段:['type', 'id', 'random']}}})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="样式表"/><link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet"/><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script><script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script><div id="应用程序"><div v-for="(items, type) in groupedItems"><h2>类型:{{ type }}</h2><b-table :fields="fields" :items="items"><模板#cell(type)="{值}">类型:{{值}}</模板></b-table>


使用手风琴

的示例

此示例使用手风琴来允许打开/关闭每个组.Accordon 只允许一个组以一种类型打开.如果您不想要这个,您可以从 b-collapse 中删除 accordion="table-accordion" 以便可以同时打开多个.>

/* 生成一些随机示例数据 */const 类型 = ['A', 'B', 'C']常量项 = [];for(让我= 0;我<15;我++){项目.推({类型:类型[i % 3],编号:我 + 1,随机:Math.random()})}新的 Vue({el: '#app',计算:{分组项目(){常量组 = {};this.items.forEach(item => {如果(组[项目.类型]){组[item.type].push(item);} 别的 {组[item.type] = [item];}});返回组;}},数据() {返回 {物品:物品,字段:['type', 'id', 'random']}}})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="样式表"/><link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet"/><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script><script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script><div id="应用程序"><b-card no-body class="mb-1" v-for="(group, type) in groupedItems"><b-card-header header-tag="header" class="p-0" role="tab"><b-button block v-b-toggle="`accordion-${type}`" variant="primary">输入 {{ 输入 }}</b-按钮></b-card-header><b-collapse :id="`accordion-${type}`" Accordion="table-accordion" role="tabpanel"><b-table :fields="fields" :items="group"></b-table></b-折叠></b-card>


根据评论中的请求提供的其他示例.

您可以通过再次执行相同的操作轻松添加另一个级别,但将其嵌套更深一层.

/* 生成一些随机示例数据 */const 类型 = ['A', 'B', 'C']常量项 = [];for(让我= 0;我<30;我++){项目.推({类型:类型[i % 3],组:我 % 9,编号:我 + 1,随机:Math.random()})}新的 Vue({el: '#app',计算:{分组项目(){常量组 = {};this.items.forEach(item => {if(!groups[item.type]) groups[item.type] = {};if(groups[item.type][item.group]){组[item.type][item.group].push(item);} 别的 {组[item.type][item.group] = [item];}});返回组;}},数据() {返回 {物品:物品,字段:['type', 'id', 'random']}}})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="样式表"/><link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet"/><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script><script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script><div id="应用程序"><b-card no-body class="mb-4" v-for="(groups, type) in groupedItems"><b-card-header header-tag="header" class="p-0" role="tab"><b-button block v-b-toggle="`accordion-${type}`" variant="primary">输入 {{ 输入 }}</b-按钮></b-card-header><b-collapse :id="`accordion-${type}`" visible role="tabpanel"><b-card no-body v-for="(items, group) in groups"><b-card-header header-tag="header" class="p-0" role="tab"><b-button block v-b-toggle="`accordion-group-${group}`" variant="secondary">输入{{组}}</b-按钮></b-card-header><b-collapse :id="`accordion-group-${group}`" :accordion="`table-accordion-${type}`" role="tabpanel"><b-table :fields="fields" :items="items"></b-table></b-折叠></b-card></b-折叠></b-card>

I am in the process of using bootstrap-vue table. Currently, my entire data resides in one table. Let's assume there are 10 rows in this table, and the first 5 rows contain value A in the first column while the next 5 rows contain value B in the first column.

What I want is, instead of having a single table containing complete data, I divide this table, so that on my page will appear two tables. The first table would contain all rows with values A and the second table would contain all rows with values B. In reality, I would have a lot of these unique values, so let's say, if I have 10 such values, I want 10 such individual tables based on these values. Is this possible to do?

Another idea could be, that if above is not possible, can I have collapsible rows? I am not talking about the More Details functionality, but rather, when I click on the A, all rows with value A would appear in the same table each appearing as a row in the table.

I was initially thinking of having rows that can span columns (Having grouped rows in bootstrap Vue table) but unfortunately, that is not supported by bootstrap vue-js table yet.

解决方案

You can do this by utilizing a computed property that splits your array up into groups.

This computed property will return a object, that contains a key which will be the value you're grouping on, and the value will be an array containing all items in that group.

/* Example structure that the computed property will return */
{
  A: [],
  B: [],
  C: []
}

You can then use a v-for to look each key in the groupedItems

<!-- 
  groupedItems is the computed property, containing the structure shown above.
  Will create a new table for each type/key in the `groupedItems` property.
-->
<div v-for="(group, type) in groupedItems">
  <b-table :fields="fields" :items="group"><b-table>
</div>


Example snippet:

A fairly basic example, which just display a header of the type and the table underneath.

/* Generate some random example data */
const types = ['A', 'B', 'C']
const items = [];
for(let i = 0; i < 15; i++) {
  items.push({
    type: types[i % 3],
    id: i + 1,
    random: Math.random()
  })
}

new Vue({
  el: '#app',
  computed: {
    groupedItems() {
      const groups = {};
      
      this.items.forEach(item => {
        if(groups[item.type]) {
          groups[item.type].push(item);
        } else {
          groups[item.type] = [item];
        }
      });

      return groups;
    }
  },
  data() {
    return {
      items: items,
      fields: ['type', 'id', 'random']
    }
  }
})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script>


<div id="app">
  <div v-for="(items, type) in groupedItems">
    <h2>Type: {{ type }}</h2>
    <b-table :fields="fields" :items="items">
      <template #cell(type)="{ value }">
        Type: {{ value }}
      </template>
    </b-table>
  </div>
</div>


Example utilizing an accordion

This example utilizes an accordion, to allow each group to be opened/closed. Accoridon's only allow one group to be open at a type. If you don't want this , you can remove accordion="table-accordion" from the b-collapse so multiple can be opened at the same time.

/* Generate some random example data */
const types = ['A', 'B', 'C']
const items = [];
for(let i = 0; i < 15; i++) {
  items.push({
    type: types[i % 3],
    id: i + 1,
    random: Math.random()
  })
}

new Vue({
  el: '#app',
  computed: {
    groupedItems() {
      const groups = {};

      this.items.forEach(item => {
        if(groups[item.type]) {
          groups[item.type].push(item);
        } else {
          groups[item.type] = [item];
        }
      });

      return groups;
    }
  },
  data() {
    return {
      items: items,
      fields: ['type', 'id', 'random']
    }
  }
})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-card no-body class="mb-1" v-for="(group, type) in groupedItems">
    <b-card-header header-tag="header" class="p-0" role="tab">
      <b-button block v-b-toggle="`accordion-${type}`" variant="primary">
        Type {{ type }}
      </b-button>
    </b-card-header>
    <b-collapse :id="`accordion-${type}`" accordion="table-accordion" role="tabpanel">
      <b-table :fields="fields" :items="group"></b-table>
    </b-collapse>
  </b-card>
</div>


Additional example based on request in comments.

You can easily add another level by doing the same thing again, but nesting it one level deeper.

/* Generate some random example data */
const types = ['A', 'B', 'C']
const items = [];
for(let i = 0; i < 30; i++) {
  items.push({
    type: types[i % 3],
    group: i % 9,
    id: i + 1,
    random: Math.random()
  })
}

new Vue({
  el: '#app',
  computed: {
    groupedItems() {
      const groups = {};

      this.items.forEach(item => {
        if(!groups[item.type]) groups[item.type] = {};

        if(groups[item.type][item.group]) {
          groups[item.type][item.group].push(item);
        } else {
          groups[item.type][item.group] = [item];
        }
      });

      return groups;
    }
  },
  data() {
    return {
      items: items,
      fields: ['type', 'id', 'random']
    }
  }
})

<link href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.15.0/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-card no-body class="mb-4" v-for="(groups, type) in groupedItems">
    <b-card-header header-tag="header" class="p-0" role="tab">
      <b-button block v-b-toggle="`accordion-${type}`" variant="primary">
        Type {{ type }}
      </b-button>
    </b-card-header>
    <b-collapse :id="`accordion-${type}`" visible role="tabpanel">
      <b-card no-body v-for="(items, group) in groups">
        <b-card-header header-tag="header" class="p-0" role="tab">
          <b-button block v-b-toggle="`accordion-group-${group}`" variant="secondary">
            Type {{ group }}
          </b-button>
        </b-card-header>
        <b-collapse :id="`accordion-group-${group}`"  :accordion="`table-accordion-${type}`" role="tabpanel">
          <b-table :fields="fields" :items="items"></b-table>
        </b-collapse>
      </b-card>
    </b-collapse>
  </b-card>
</div>

这篇关于根据来自 API 的响应显示多个引导 VueJS 表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆