'tag.htm'; break; case 'flag': $pre .= $default_pre .= 'flag.htm'; break; case 'my': $pre .= $default_pre .= 'my.htm'; break; case 'my_password': $pre .= $default_pre .= 'my_password.htm'; break; case 'my_bind': $pre .= $default_pre .= 'my_bind.htm'; break; case 'my_avatar': $pre .= $default_pre .= 'my_avatar.htm'; break; case 'home_article': $pre .= $default_pre .= 'home_article.htm'; break; case 'home_comment': $pre .= $default_pre .= 'home_comment.htm'; break; case 'user': $pre .= $default_pre .= 'user.htm'; break; case 'user_login': $pre .= $default_pre .= 'user_login.htm'; break; case 'user_create': $pre .= $default_pre .= 'user_create.htm'; break; case 'user_resetpw': $pre .= $default_pre .= 'user_resetpw.htm'; break; case 'user_resetpw_complete': $pre .= $default_pre .= 'user_resetpw_complete.htm'; break; case 'user_comment': $pre .= $default_pre .= 'user_comment.htm'; break; case 'single_page': $pre .= $default_pre .= 'single_page.htm'; break; case 'search': $pre .= $default_pre .= 'search.htm'; break; case 'operate_sticky': $pre .= $default_pre .= 'operate_sticky.htm'; break; case 'operate_close': $pre .= $default_pre .= 'operate_close.htm'; break; case 'operate_delete': $pre .= $default_pre .= 'operate_delete.htm'; break; case 'operate_move': $pre .= $default_pre .= 'operate_move.htm'; break; case '404': $pre .= $default_pre .= '404.htm'; break; case 'read_404': $pre .= $default_pre .= 'read_404.htm'; break; case 'list_404': $pre .= $default_pre .= 'list_404.htm'; break; default: $pre .= $default_pre .= theme_mode_pre(); break; } if ($config['theme']) { $conffile = APP_PATH . 'view/template/' . $config['theme'] . '/conf.json'; $json = is_file($conffile) ? xn_json_decode(file_get_contents($conffile)) : array(); } !empty($json['installed']) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . ($id ? $id . '_' : '') . $pre; (empty($path_file) || !is_file($path_file)) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . $pre; if (!empty($config['theme_child']) && is_array($config['theme_child'])) { foreach ($config['theme_child'] as $theme) { if (empty($theme) || is_array($theme)) continue; $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . ($id ? $id . '_' : '') . $pre; !is_file($path_file) and $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . $pre; } } !is_file($path_file) and $path_file = APP_PATH . ($dir ? 'plugin/' . $dir . '/view/htm/' : 'view/htm/') . $default_pre; return $path_file; } function theme_mode_pre($type = 0) { global $config; $mode = $config['setting']['website_mode']; $pre = ''; if (1 == $mode) { $pre .= 2 == $type ? 'portal_category.htm' : 'portal.htm'; } elseif (2 == $mode) { $pre .= 2 == $type ? 'flat_category.htm' : 'flat.htm'; } else { $pre .= 2 == $type ? 'index_category.htm' : 'index.htm'; } return $pre; } ?>javascript - How to create a search filter using Vue js from API Data? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create a search filter using Vue js from API Data? - Stack Overflow

programmeradmin0浏览0评论

I'm fetching data from the Star Wars API, more specifically people and it's working. I want to create a search filter function that as I start typing, only the names with those letters appear. This is my code to fetch the data in StarWarsPeopleComponent.vue file:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <input type='text' v-model="search" placeholder='Search people...'/><br>

                {{ getAllStarWarsPeople() }}

                <ul>
                    <li v-for="person in people.results">
                        {{ person.name }}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>

    export default {

        name: "StarWarsPeopleComponent",

        data() {
            return {
                people: [],
                search: ''
            }
        },

        mounted() {
            console.log('Component mounted.')
        },

        methods:{

            getAllStarWarsPeople() {

                fetch("/")
                    .then(response=>response.json())
                    .then(data=>{
                        this.people=data;
                    })

            }

        }
    }
</script>

Note how I access the data in the v-for with people.results.

Here is my ponent updated with a puted function that I created but now the data isn't showing and I get this error:

[Vue warn]: Error in render: "TypeError: this.people.filter is not a function".

I'm pretty new to Vue js and I don't know what this means or how to fix it. Can anyone help?

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <input type='text' v-model="search" placeholder='Search people...'/><br>

                {{ getAllStarWarsPeople() }}

                <ul>
                    <li v-for="person in filteredPeople">
                        {{ person.name }}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>

    export default {

        name: "StarWarsPeopleComponent",

        data() {
            return {
                people: [],
                search: ''
            }
        },
        mounted() {
            console.log('Component mounted.')
        },
        methods:{

            getAllStarWarsPeople() {

                fetch("/")
                    .then(response=>response.json())
                    .then(data=>{
                        this.people=data;
                    })

            }

        },
        puted: {
            filteredPeople: function() {
                return this.people.filter((person) => {
                   return person.name.match(this.search);
                });
            }
        }
    }
</script>

I'm fetching data from the Star Wars API, more specifically people and it's working. I want to create a search filter function that as I start typing, only the names with those letters appear. This is my code to fetch the data in StarWarsPeopleComponent.vue file:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <input type='text' v-model="search" placeholder='Search people...'/><br>

                {{ getAllStarWarsPeople() }}

                <ul>
                    <li v-for="person in people.results">
                        {{ person.name }}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>

    export default {

        name: "StarWarsPeopleComponent",

        data() {
            return {
                people: [],
                search: ''
            }
        },

        mounted() {
            console.log('Component mounted.')
        },

        methods:{

            getAllStarWarsPeople() {

                fetch("https://swapi.co/api/people/")
                    .then(response=>response.json())
                    .then(data=>{
                        this.people=data;
                    })

            }

        }
    }
</script>

Note how I access the data in the v-for with people.results.

Here is my ponent updated with a puted function that I created but now the data isn't showing and I get this error:

[Vue warn]: Error in render: "TypeError: this.people.filter is not a function".

I'm pretty new to Vue js and I don't know what this means or how to fix it. Can anyone help?

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <input type='text' v-model="search" placeholder='Search people...'/><br>

                {{ getAllStarWarsPeople() }}

                <ul>
                    <li v-for="person in filteredPeople">
                        {{ person.name }}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>

    export default {

        name: "StarWarsPeopleComponent",

        data() {
            return {
                people: [],
                search: ''
            }
        },
        mounted() {
            console.log('Component mounted.')
        },
        methods:{

            getAllStarWarsPeople() {

                fetch("https://swapi.co/api/people/")
                    .then(response=>response.json())
                    .then(data=>{
                        this.people=data;
                    })

            }

        },
        puted: {
            filteredPeople: function() {
                return this.people.filter((person) => {
                   return person.name.match(this.search);
                });
            }
        }
    }
</script>
Share asked Jan 16, 2020 at 1:35 Ryan SacksRyan Sacks 5241 gold badge15 silver badges48 bronze badges 2
  • in vue, this cannot be used in foreign function. use filter function like in Evan answer instead. – Khairul Habib Commented Jan 16, 2020 at 2:07
  • swapi is not really a good option here, as is no possibility to search by keyword. That would not be a problem if swapi in fact returns all people by that request, but it does not, it's paging it, so you would need to make subsequent requests to actually get all people to filter from, as people url just returns 10 people and gives you a next property like: "next": "https://swapi.co/api/people/?page=2", then page 3 etc. Consider using another free api instead unless you want to fire multiple requests and store all people in an array to filter from :) – AVJT82 Commented Jan 16, 2020 at 17:05
Add a ment  | 

2 Answers 2

Reset to default 5

use "created()" to call getAllStarWarsPeople() when ponent is loaded.

add getAllStarWarsPeople as "@keyup" on input field.

try this:

<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-8">
        <input
          type="text"
          v-model.trim="search"
          placeholder="Search people..."
          @keyup="getAllStarWarsPeople"
        /><br />
        <ul>
          <li v-for="person in people" :key="person.id">
            {{ person.name }}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "StarWarsPeopleComponent",

  data() {
    return {
      people: [],
      search: ""
    };
  },

  mounted() {
    console.log("Component mounted.");
  },

  methods: {
    getAllStarWarsPeople() {
      fetch("https://swapi.dev/api/people/")
        .then(response => response.json())
        .then(res => {
          if (this.search) {
            this.people = res.results.filter(people =>
              people.name.toLowerCase().includes(this.search.toLowerCase())
            );
          } else {
            this.people = res.results;
          }
        });
    }
  },
  created() {
    this.getAllStarWarsPeople();
  }
};
</script>

JsFiddle here:

new Vue({
  el: "#app",
  data: {
    people: [],
    search: ""
  },
  methods: {
    getAllStarWarsPeople() {
      fetch("https://swapi.dev/api/people/")
        .then(response => response.json())
        .then(res => {
          if (this.search) {
            this.people = res.results.filter(people =>
              people.name.toLowerCase().includes(this.search.toLowerCase())
            );
          } else {
            this.people = res.results;
          }
        });
    }
  },
  created() {
    this.getAllStarWarsPeople();
  }
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
  <div id="app">
    <input
      type="text"
      v-model.trim="search"
      placeholder="Search people..."
      @keyup="getAllStarWarsPeople"
    /><br />
    <ul>
      <li v-for="person in people" :key="person.id">
        {{ person.name }}
      </li>
    </ul>
</div>

You can use like

puted: {
  filteredPeople() {
    if (this.people) {
      return this.people.filter((person) => {
         return person.name.match(this.search);
      });
    }
    return false;
  }
}

发布评论

评论列表(0)

  1. 暂无评论