Edit in JSFiddle

// Source: http://www.canadastop100.com/
console.log(Vue.version);
var laptopData = [{
  "name": "3M Canada Company",
  "Community Involvement": 10,
  "Employee Engagement & Performance": 7,
  "Financial Benefits & Compensation": 9,
  "Health & Family-Friendly Benefits": 9,
  "Physical Workplace": 10,
  "Training & Skills Development": 9,
  "Vacation & Personal Time-Off": 6,
  "Work Atmosphere & Communications": 10,
  "Total Score": 70
}, {
  "name": "Aboriginal Peoples Television Network Inc. / APTN",
  "Community Involvement": 9,
  "Employee Engagement & Performance": 6,
  "Financial Benefits & Compensation": 7,
  "Health & Family-Friendly Benefits": 9,
  "Physical Workplace": 7,
  "Training & Skills Development": 9,
  "Vacation & Personal Time-Off": 9,
  "Work Atmosphere & Communications": 9,
  "Total Score": 65
}, {
  "name": "Accenture Inc.",
  "Community Involvement": 10,
  "Employee Engagement & Performance": 9,
  "Financial Benefits & Compensation": 7,
  "Health & Family-Friendly Benefits": 9,
  "Physical Workplace": 7,
  "Training & Skills Development": 7,
  "Vacation & Personal Time-Off": 6,
  "Work Atmosphere & Communications": 9,
  "Total Score": 64
}];
console.log('test');
Vue.component('data-grid', {
  template: '#data-template',
  props: {
    data: Array,
    columns: Array,
    filterKey: String
  },
  data: function() {
    var sortOrders = {}
    this.columns.forEach(function(key) {
      sortOrders[key] = 1
    })
    return {
      sortKey: '',
      sortOrders: sortOrders
    }
  },
  computed: {
    filteredData: function() {
      var sortKey = this.sortKey
      var filterKey = this.filterKey && this.filterKey.toLowerCase()
      var order = this.sortOrders[sortKey] || 1
      var data = this.data
      if (filterKey) {
        data = data.filter(function(row) {
          return Object.keys(row).some(function(key) {
            return String(row[key]).toLowerCase().indexOf(filterKey) > -1
          })
        })
      }
      if (sortKey) {
        data = data.slice().sort(function(a, b) {
          a = a[sortKey]
          b = b[sortKey]
          return (a === b ? 0 : a > b ? 1 : -1) * order
        })
      }
      return data
    }
  },
  filters: {
    capitalize: function(str) {
      return str.charAt(0).toUpperCase() + str.slice(1)
    }
  },
  methods: {
    sortBy: function(key) {
      this.sortKey = key
      this.sortOrders[key] = this.sortOrders[key] * -1
    }
  }
})

var vueApp = new Vue({
  el: '#vue-app',
  data: {
    searchQuery: '',
    gridColumns: Object.keys(laptopData[0]),
    gridData: laptopData
  }
})
<div id="vue-app">
  <form id="search">
    Search
    <input name="query" v-model="searchQuery">
  </form>
  <data-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery">
  </data-grid>
</div>
<script type="text/x-template" id="data-template">
  <table>
    <thead>
      <tr>
        <th v-for="key in columns" @click="sortBy(key)" :class="{ active: sortKey == key }">
          {{ key | capitalize }}
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="entry in filteredData">
        <td v-for="key in columns">
          {{entry[key]}}
        </td>
      </tr>
    </tbody>
  </table>
</script>
table {
  border: 2px solid rgb(102, 153, 255);
  border-radius: 3px;
  background-color: #fff;
}

th {
  background-color: rgb(102, 153, 255);
  color: rgba(255, 255, 255, 0.66);
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

td {
  background-color: #f9f9f9;
}

th,
td {
  min-width: 120px;
  padding: 10px 20px;
}

th.active {
  color: #fff;
}

th.active .arrow {
  opacity: 1;
}

.arrow {
  display: inline-block;
  vertical-align: middle;
  width: 0;
  height: 0;
  margin-left: 5px;
  opacity: 0.66;
}

.arrow.asc {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 4px solid #fff;
}

.arrow.dsc {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid #fff;
}

External resources loaded into this fiddle: