Home > database >  VueJS - Pull results from a separate component
VueJS - Pull results from a separate component

Time:04-21

I have found an excellent example for creating URL filters. I would like the results to be in a separate component though. In this example, all the code is in one file. Can someone help me to move the results to a separate component and also ensure the URL filters work when the different selections are made?

<template>
  <div id="app">
    <div id="app">
      <h2>Items</h2>

      <p>
        <input type="search" placeholder="Filter by name" v-model="filter" />
        <input
          type="checkbox"
          value="person"
          id="personType"
          v-model="typeFilter"
        />
        <label for="personType">Only People</label>

        <input type="checkbox" value="cat" id="catType" v-model="typeFilter" />
        <label for="catType">Only Cats</label>

        <input type="checkbox" value="dog" id="dogType" v-model="typeFilter" />
        <label for="dogType">Only Dogs</label>
      </p>

      <ul>
        <li v-for="item in items" :key="item">
          {{ item.name }} ({{ item.type }})
        </li>
      </ul>
    </div>
  </div>
  <!-- <Result v-for="item in items" :key="item" /> -->
</template>

<script>
//import Result from "@/components/Result.vue";

export default {
  components: {
    //Result,
  },
  data: function () {
    return {
      //  allItems: ITEMS,
      filter: "",
      typeFilter: [],
      ITEMS: [
        { name: "Ray", type: "person" },
        { name: "Lindy", type: "person" },
        { name: "Jacob", type: "person" },
        { name: "Lynn", type: "person" },
        { name: "Noah", type: "person" },
        { name: "Jane", type: "person" },
        { name: "Maisie", type: "person" },
        { name: "Carol", type: "person" },
        { name: "Ashton", type: "person" },
        { name: "Weston", type: "person" },
        { name: "Sammy", type: "cat" },
        { name: "Aleese", type: "cat" },
        { name: "Luna", type: "cat" },
        { name: "Pig", type: "cat" },
        { name: "Cayenne", type: "dog" },
      ],
    };
  },

  created() {
    let qp = new URLSearchParams(window.location.search);
    let f = qp.get("filter");
    if (f) this.filter = qp.get("filter");
    let tf = qp.get("typeFilter");
    if (tf) this.typeFilter = tf.split(",");
  },
  computed: {
    items() {
      this.updateURL();
      return this.ITEMS.filter((a) => {
        if (
          this.filter !== "" &&
          a.name.toLowerCase().indexOf(this.filter.toLowerCase()) === -1
        )
          return false;
        if (this.typeFilter.length && !this.typeFilter.includes(a.type))
          return false;
        return true;
      });
    },
  },
  methods: {
    updateURL() {
      let qp = new URLSearchParams();
      if (this.filter !== "") qp.set("filter", this.filter);
      if (this.typeFilter.length) qp.set("typeFilter", this.typeFilter);
      history.replaceState(null, null, "?"   qp.toString());
    },
  },
};
</script>

CodePudding user response:

You need to read about props in component (vuejs.org/v2/guide/components-props.html).

I wrote you an example but not tested, hope it will be helpful.

<template>
  <div id="app">
    <h2>Items</h2>

    <p>
      <input type="search" placeholder="Filter by name" v-model="filter" />
      <input
        type="checkbox"
        value="person"
        id="personType"
        v-model="typeFilter"
      />
      <label for="personType">Only People</label>

      <input type="checkbox" value="cat" id="catType" v-model="typeFilter" />
      <label for="catType">Only Cats</label>

      <input type="checkbox" value="dog" id="dogType" v-model="typeFilter" />
      <label for="dogType">Only Dogs</label>
    </p>

    <ul>
      <li v-for="item in items" :key="item">
        {{ item.name }} ({{ item.type }})
      </li>
    </ul>

    <Result v-bind:items="filteredItems" />
  </div>
</template>

<script>
import Result from "@/components/Result.vue";

export default {
  components: {
    Result,
  },
  data: function () {
    return {
      filter: "",
      typeFilter: [],
      items: [
        { name: "Ray", type: "person" },
        { name: "Lindy", type: "person" },
        { name: "Jacob", type: "person" },
        { name: "Lynn", type: "person" },
        { name: "Noah", type: "person" },
        { name: "Jane", type: "person" },
        { name: "Maisie", type: "person" },
        { name: "Carol", type: "person" },
        { name: "Ashton", type: "person" },
        { name: "Weston", type: "person" },
        { name: "Sammy", type: "cat" },
        { name: "Aleese", type: "cat" },
        { name: "Luna", type: "cat" },
        { name: "Pig", type: "cat" },
        { name: "Cayenne", type: "dog" },
      ],
    };
  },

  created() {
    let qp = new URLSearchParams(window.location.search);
    let f = qp.get("filter");
    if (f) {
      this.filter = qp.get("filter");
    }
    let tf = qp.get("typeFilter");
    if (tf) {
      this.typeFilter = tf.split(",");
    }
  },
  computed: {
    filteredItems() {
      this.updateURL();
      return this.items.filter((item) => item.name.toLowerCase().includes(this.filter.toLowerCase()));
    },
  },
  methods: {
    updateURL() {
      let qp = new URLSearchParams();
      if (this.filter !== "") {
        qp.set("filter", this.filter);
      }
      if (this.typeFilter.length) {
        qp.set("typeFilter", this.typeFilter);
      }
      history.replaceState(null, null, "?"   qp.toString());
    },
  },
};
</script>
<template>
  <div >
    <ul>
      <li v-for="item in items" :key="item">
        {{ item.name }} ({{ item.type }})
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ['items'],
};
</script>
  • Related