<div id="shopping-list">
  <table class="pf-c-table pf-m-grid-lg" role="grid" aria-label="Shopping list">
  <caption>
    <span id="caption-text">{{totalItemsChecked}} of {{totalItems}} items checked</span>
    &nbsp;
    <button class="pf-c-button pf-m-primary" type="button" @click="doCheckAllProducts" :disabled="checkAllBtnDisabled">
      Check all
    </button>
    <button class="pf-c-button pf-m-secondary" type="button" @click="doUncheckAllProducts" :disabled="uncheckAllBtnDisabled">
      Uncheck all
    </button>
  </caption>
  <thead>
    <tr>
      <td />
      <th scope="col">
        Item
      </th>
      <th scope="col">
        Quantity
      </th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(product, index) in products" :key="index" :class="[{'checked': product.isChecked}]">
      <td class="pf-c-table__check">
        <input type="checkbox" name="product.name" :aria-labelledby="`item-${index}-${product.name}`" v-model="product.isChecked"/>
      </td>
      <th data-label="Item">
        <div id="`item-${index}-${product.name}`">{{product.name}}</div>
      </th>
      <td data-label="Quantity">
        {{product.quantity}}
      </td>
    </tr>
  </tbody>
</table>
</div>
table tr.checked {
  text-decoration: line-through;
  background-color: #ebebeb;
}

table caption span {
  padding-right: 10px;
}

table caption .pf-c-button {
  margin-right: 4px;
}
new Vue({
    el: '#shopping-list',
    data: {
        products: [
          {
            name: 'Sugar',
            quantity: '1 Cup',
            isChecked: false
          },
          {
            name: 'Butter',
            quantity: '1/2 Cup',
            isChecked: false
          },
          {
            name: 'Eggs',
            quantity: '2',
            isChecked: true
          },
          {
            name: 'Milk',
            quantity: '1/2 Cup',
            isChecked: false
          }
        ]
    },
    computed: {
      totalItems () {
        return this.products.length
      },
      totalItemsChecked () {
        return this.products.filter(p => p.isChecked).length
      },
      checkAllBtnDisabled () {
        return this.totalItemsChecked === this.totalItems
      },
      uncheckAllBtnDisabled () {
        return this.totalItemsChecked === 0
      }
    },
    methods: {
      doCheckAllProducts () {
        if (this.checkAllBtnDisabled) return
        this.products.map(p => p.isChecked = true)
      },
      doUncheckAllProducts () {
        if (this.uncheckAllBtnDisabled) return
        this.products.map(p => p.isChecked = false)
      }
    }
})
View Compiled

External CSS

  1. https://unpkg.com/@patternfly/patternfly/patternfly.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js