bootstrap-vue 使用 colgroup 将列与列 header 分组

bootstrap-vue using colgroup to group the column with column header

我必须创建 table,如下图所示的设计,使用 Bootstrap Vue

此处男性和女性按各自的部分分组,这可以使用简单的 <td><col-group>

来完成

bootstrap-vue文档中有插槽table-colgroup,但我没有找到在这种情况下使用的方法。

我已经在下面的代码片段中实现了 table:

Vue.config.productionTip = false
Vue.component('icons', {
  template: '<a><slot></slot></a>'
})
new Vue({
  el: '#app',
  methods: {
    addService() {
      this.model.services.push({});
    }
  },
  computed: {
    sec_a_male: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_a_male) || 0)
      }, 0)
    },
    sec_a_female: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_a_female) || 0)
      }, 0)
    },
    sec_b_male: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_b_male) || 0)
      }, 0)
    },
    sec_b_female: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_b_female) || 0)
      }, 0)
    }
  },
  data: {
    model: {
      services: []
    },
    fields: [{
        key: "class",
        label: "Class"
      },
      {
        key: "section_a_male",
        label: "Male"
      },
      {
        key: "section_a_female",
        label: "Female"
      },
      {
        key: "section_b_male",
        label: "Male"
      },
      {
        key: "section_b_female",
        label: "Male"
      }
    ]
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />

<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-card header-tag="header" footer-tag="footer">
    <template slot="header" class="mb-0">
                    <button type="button" class="btn btn-primary btn-sm" @click.prevent="addService">
                        <icons :icon="['fas', 'plus']" /> Add Items/Service</button>
                </template>
    <b-card-body>
   
      <b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
              <template slot="top-row" slot-scope="data">
          
            <td rowspan="1"></td>
            <th colspan="2" scope="colgroup">Section A</th>
            <th colspan="2" scope="colgroup">Section B</th>
 
        </template>

        <template slot="class" slot-scope="data">

<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />

        </template>
        <template slot="section_a_male" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
         </template>
        <template slot="section_a_female" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
         </template>
        <template slot="section_b_male" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
         </template>
        <template slot="section_b_female" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
         </template>

        <template slot="bottom-row" slot-scope="data">
          <td>Total</td>
          <td>{{sec_a_male}}</td>
          <td>{{sec_a_female}}</td>
          <td>{{sec_b_male}}</td>
          <td>{{sec_b_female}}</td>
        </template>
        <template slot="table-colgroup">
         <col>
         <col span="2">
         <col span="2">
        </template>



      </b-table>

    </b-card-body>
  </b-card>
</div>

预期输出:

请帮忙!

这可能会让您入门。您可以将 class bg-danger 添加到您的 td 元素,您可以将 variants/classes 添加到您的字段数组。

Vue.config.productionTip = false
Vue.component('icons', {
  template: '<a><slot></slot></a>'
})
new Vue({
  el: '#app',
  methods: {
    addService() {
      this.model.services.push({});
    }
  },
  computed: {
    sec_a_male: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_a_male) || 0)
      }, 0)
    },
    sec_a_female: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_a_female) || 0)
      }, 0)
    },
    sec_b_male: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_b_male) || 0)
      }, 0)
    },
    sec_b_female: function() {
      return this.model.services.reduce(function(a, c) {
        return a + Number((c.section_b_female) || 0)
      }, 0)
    }
  },
  data: {
    model: {
      services: []
    },
    fields: [{
        key: "class",
        label: "Class"
      },
      {
        key: "section_a_male",
        label: "Male",
        variant: 'danger'
      },
      {
        key: "section_a_female",
        label: "Female",
        variant: 'danger'
      },
      {
        key: "section_b_male",
        label: "Male",
        variant: 'warning'
      },
      {
        key: "section_b_female",
        label: "Male",
        variant: 'warning'
      }
    ]
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />

<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-card header-tag="header" footer-tag="footer">
    <template slot="header" class="mb-0">
                    <button type="button" class="btn btn-primary btn-sm" @click.prevent="addService">
                        <icons :icon="['fas', 'plus']" /> Add Items/Service</button>
                </template>
    <b-card-body>
      <b-table responsive bordered hover caption-top :fields="fields" :items="model.services" foot-clone>
        <template slot="class" slot-scope="data">

<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />

        </template>
        <template slot="section_a_male" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
         </template>
        <template slot="section_a_female" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
         </template>
        <template slot="section_b_male" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
         </template>
        <template slot="section_b_female" slot-scope="data">
        
 <b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
         </template>

        <template slot="bottom-row" slot-scope="data">
          <td>Total</td>
          <td class="bg-danger">{{sec_a_male}}</td>
          <td class="bg-danger">{{sec_a_female}}</td>
          <td class="bg-warning">{{sec_b_male}}</td>
          <td class="bg-warning">{{sec_b_female}}</td>
        </template>
      </b-table>

    </b-card-body>
  </b-card>
</div>

boostrap-vue 之前没有,当前版本 boostrap-vue v2.0.0-rc.14 刚刚发布了新更改,支持 header 行。

  <b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
    <template slot="thead-top" slot-scope="{}">
            <tr>
              <th></th>
              <th class="text-center" colspan="2">Section A</th>
              <th class="text-center" colspan="2">Section B</th>
            </tr>
         </template>
  </b-table>

这可以通过使用 thead-top 槽来完成,这里有进一步的解释

https://bootstrap-vue.js.org/docs/components/table#adding-additional-rows-to-the-header

这可能会给出另一种情况:

<b-table class ="table" :fields="fields" :items="items">
    <template slot="bottom-row" slot-scope="{}">                        
        <th colspan="5" class="text-center">No Data</th>                          
    </template>
</b-table>
  • 从 :fields
  • 获取 header table
  • 底部带有文本“无数据”的默认行居中对齐。 Post 条件:项目为空。

检查下面的 table 输出: