[Vuejs]-Nested Single file Component problem with Grid component

1👍

You’ve got your code in all the wrong places. Most likely due to the lack of understanding of the Single File Components concept and Component Basics.

Here’s me literally copy and pasting code from the original fiddle into their respective components.

Your chart.vue should look like this:

<template>
  <div id="demo">
    <form id="search">
      Search
      <input name="query" v-model="searchQuery">
    </form>
    <demo-grid :heroes="gridData" :columns="gridColumns" :filter-key="searchQuery"></demo-grid>
  </div>
</template>

<script>
import DemoGrid from "./grid.vue";
export default {
  name: "Chart",
  components: {
    DemoGrid
  },
  data() {
    return {
      searchQuery: "",
      gridColumns: ["name", "power"],
      gridData: [
        { name: "Chuck Norris", power: Infinity },
        { name: "Bruce Lee", power: 9000 },
        { name: "Jackie Chan", power: 7000 },
        { name: "Jet Li", power: 8000 }
      ]
    };
  }
};
</script>

Your grid.vue should look like this:

<template>
  <table>
    <thead>
      <tr>
        <th
          v-for="(key, index) in columns"
          :key="index"
          :class="{ active: sortKey == key }"
          @click="sortBy(key)"
        >
          {{ key | capitalize }}
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(entry, index) in filteredHeroes" :key="index">
        <td v-for="(key, index) in columns" :key="index">{{ entry[key] }}</td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  name: "DemoGrid",
  props: {
    heroes: Array,
    columns: Array,
    filterKey: String
  },
  data: function() {
    const sortOrders = {};
    this.columns.forEach(function(key) {
      sortOrders[key] = 1;
    });
    return {
      sortKey: "",
      sortOrders: sortOrders
    };
  },
  computed: {
    filteredHeroes() {
      const sortKey = this.sortKey;
      const filterKey = this.filterKey && this.filterKey.toLowerCase();
      const order = this.sortOrders[sortKey] || 1;
      let heroes = this.heroes;
      if (filterKey) {
        heroes = heroes.filter(function(row) {
          return Object.keys(row).some(function(key) {
            return (
              String(row[key])
                .toLowerCase()
                .indexOf(filterKey) > -1
            );
          });
        });
      }
      if (sortKey) {
        heroes = heroes.slice().sort(function(a, b) {
          a = a[sortKey];
          b = b[sortKey];
          return (a === b ? 0 : a > b ? 1 : -1) * order;
        });
      }
      return heroes;
    }
  },
  filters: {
    capitalize(str) {
      return str.charAt(0).toUpperCase() + str.slice(1);
    }
  },
  methods: {
    sortBy(key) {
      this.sortKey = key;
      this.sortOrders[key] = this.sortOrders[key] * -1;
    }
  }
};
</script>

<style scoped>
table {
  border: 2px solid #42b983;
  border-radius: 3px;
  background-color: #fff;
}
th {
  background-color: #42b983;
  color: rgba(255, 255, 255, 0.66);
  cursor: pointer;
  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;
}
</style>

Assuming both components are in the same directory.

👤Cue

Leave a comment