javascript - 根据来自 API 的响应显示多个引导 VueJS 表
问题描述
我正在使用 bootstrap-vue 表。目前,我的整个数据都驻留在一张表中。假设该表中有 10 行,前 5 行包含A
第一列中的值,而接下来的 5 行包含B
第一列中的值。
我想要的是,我不是有一个包含完整数据的表,而是划分这个表,这样我的页面上就会出现两个表。第一个表将包含所有具有值A
的行,第二个表将包含所有具有值的行B
。实际上,我会有很多这些独特的值,所以假设我有 10 个这样的值,我想要基于这些值的 10 个这样的单独的表。这可能吗?
另一个想法可能是,如果以上不可能,我可以有可折叠的行吗?我不是在谈论More Details
功能,而是当我单击 时A
,所有具有值的行都A
将出现在同一个表中,每个行都在表中显示为一行。
我最初考虑让行可以跨列(在引导 Vue 表中对行进行分组),但不幸的是,引导 vue-js 表还不支持。
解决方案
您可以通过使用将数组拆分为组的计算属性来做到这一点。
此计算属性将返回一个对象,其中包含一个键,该键将是您要分组的值,该值将是一个包含该组中所有项目的数组。
/* Example structure that the computed property will return */
{
A: [],
B: [],
C: []
}
然后,您可以使用 av-for
查看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>
示例片段:
一个相当基本的示例,它只显示类型的标题和下面的表格。
/* 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>
使用手风琴的例子
此示例使用手风琴,以允许打开/关闭每个组。Accoridon 只允许在一个类型中打开一个组。如果你不想要这个,你可以accordion="table-accordion"
从b-collapse
so中移除多个可以同时打开。
/* 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>
基于评论请求的附加示例。
您可以通过再次执行相同的操作轻松添加另一个级别,但将其嵌套更深一层。
/* 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>
推荐阅读
- python - 多处理张量流的每个 GPU 的进程数
- sql - 将 sql 查询转换为 Django 查询集?
- c++ - C++ | 以漂亮的方式将树(不一定是二进制)打印到标准输出
- python - Raspberry pi GPIO 输出工作但不输入
- systemd - 为什么systemd不重启服务?
- android - 是否可以在系统范围内使用文本观察器?
- php - 我应该如何从 php 中的两个二维数组中获取缺失值
- python - Tensorflow Multiple processes with less GPUs Model inference
- neo4j - Use neo4j cypher to find most connected nodes that meet given criteria for connection. eg. authors who co-author books
- python - How to apply De-Morgan's Law to a string of Boolean expression in Python?