JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

<div id="demo" class="container">
  <input v-model="search" class="form-control" placeholder="Filter users by name or age">

  <table class="table table-striped">
    <thead>
      <tr>
        <th v-for="column in columns">
          <a href="#" @click="sortBy(column)" :class="{ active: sortKey === column }">
            {{ column }}
          </a>
        </th>
      </tr>
    </thead>

    <tbody>
      <tr v-for="user in filteredUsers">
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
      </tr>
    </tbody>
  </table>

  <div class="form-group">
    <label>Name</label>
    <input type="text" class="form-control" v-model="newUser.name">
  </div>

  <div class="form-group">
    <label>Age</label>
    <input type="name" class="form-control" v-model.number="newUser.age">
  </div>

  <button type="submit" class="btn btn-primary" @click="addUser">Add</button>
</div>

CSS

body {
  margin: 2em 0;
}

a {
  font-weight: normal;
  color: blue;
}

a.active {
  font-weight: bold;
  color: black;
}

JavaScript

new Vue({
  el: '#demo',
  data: () => ({
    sortKey: 'name',
    reverse: false,
    search: '',
    columns: [ 'name', 'age' ],
    newUser: {},
    users: [
      { name: 'John', age: 50 },
      { name: 'Jane', age: 22 },
      { name: 'Paul', age: 34 },
      { name: 'Kate', age: 15 },
      { name: 'Amanda', age: 65 },
      { name: 'Steve', age: 38 },
      { name: 'Keith', age: 21 },
      { name: 'Don', age: 50 },
      { name: 'Susan', age: 21 },
    ],
  }),
  computed: {
    sortedUsers() {
      const k = this.sortKey;
      return [...this.users].sort((a, b) => {
        return (a[k] < b[k] ? -1 : a[k] > b[k] ? 1 : 0) * [ 1, -1 ][+this.reverse];
      });
    },
    filteredUsers() {
      const s = this.search.toLowerCase();
      return this.sortedUsers.filter(n => {
        return Object.values(n).some(m => m.toString().toLowerCase().includes(s));
      });
    },
  },
  methods: {
    sortBy(sortKey) {
      this.reverse = (this.sortKey == sortKey) ? !this.reverse : false;
      this.sortKey = sortKey;
    },
    addUser() {
      this.users.push(this.newUser);
      this.newUser = {};
    },
  },
});