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="app" class="container">
  <input v-model="search" class="form-control" placeholder="Filter by anything">

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

    <tbody>
      <tr v-for="n in filteredTokens_VMP">
        <td v-for="col in columns">{{ getNested(n, col.key) }}</td>
      </tr>
    </tbody>
  </table>
</div>

CSS

body {
  margin: 2em 0;
}

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

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

JavaScript

const includes = (obj, str) => Object
  .values(obj)
  .some(n => n instanceof Object
    ? includes(n, str)
    : `${n}`.toLowerCase().includes(str)
  );

const getNested = (root, path) => path
  .split('.')
  .reduce((p, c) => p != null ? p[c] : p, root);


new Vue({
  el: '#app',
  data: () => ({
    sort: {
      key: 'name.first',
      reverse: false,
    },
    search: '',
    columns: [
      { key:               'id', title:             '#' },
      { key:       'name.first', title:           'Имя' },
      { key:        'name.last', title:       'Фамилия' },
      { key:              'age', title:       'Возраст' },
      { key: 'treatment_method', title: 'Метод лечения' },
    ],
    tokens_VMP: [
      { id:  1, name: { first:  'John', last:     'Doe' }, age:   23, treatment_method: 'Surgery' },
      { id:  2, name: { first:  'Jane', last:   'Smith' }, age:   41, treatment_method: null },
      { id:  3, name: { first:  'Mike', last: 'Johnson' }, age:   56, treatment_method: 'Physical therapy' },
      { id:  4, name: { first: 'Sarah', last:   'Brown' }, age:    8, treatment_method: 'Chemotherapy' },
      { id:  5, name: { first: 'Chris', last:  'Wilson' }, age:   95, treatment_method: 'Counseling' },
      { id:  6, name:                                null, age:   17, treatment_method: 'Acupuncture' },
      { id:  7, name: { first:  'Alex', last:  'Miller' }, age:   30, treatment_method: 'Massage therapy' },
      { id:  8, name: { first: 'Laura', last:  'Taylor' }, age: null, treatment_method: 'Homeopathy' },
      { id:  9, name: { first:   'Tom', last:   'Evans' }, age:   28, treatment_method: 'Hypnotherapy' },
      { id: 10, name: { first: 'Grace', last:   'Moore' }, age:   14, treatment_method: 'Physical exercise' },
    ],
  }),
  computed: {
    sortedTokens_VMP() {
      const reverse = this.sort.reverse ? -1 : 1;
      return this.tokens_VMP
        .map(n => [ this.getNested(n, this.sort.key), n ])
        .sort(([a], [b]) => reverse *...