javascript - 如何在使用vue js进行搜索时仅在键入时显示搜索结果

标签 javascript vue.js filter

我正在使用 vue js 创建搜索过滤器,我当前的问题是,我想显示来自 recentSearch 的数据页面创建时的历史记录,或者不显示来自 recentSearch 的所有 json 数据,然后当我开始输入时,它将从 searchProduct 中检索过滤器数据

我的json格式在searchProduct.php

{"result" : [
    { product_name: 'mike', business_name: 'student' },
    { product_name: 'beckham john', business_name: 'footballer' },
    { product_name: 'walcott', business_name: 'footballer' },
    { product_name: 'cech', business_name: 'footballer' },
    { product_name: 'jordan', business_name: 'actor' },
    { product_name: 'tom', business_name: 'actor' },
    { product_name: 'john', business_name: 'actor' }
],
"recent" : [
    { product_name: 'mike', business_name: 'student' },
    { product_name: 'beckham john', business_name: 'footballer' },
    { product_name: 'walcott', business_name: 'footballer' }
]}

HTML 范例

<div id="SearchVueContenPage">
<input type="search" v-model="q" name="q"/>
    <ul>
        <li v-for="row in filterSearchs" >{{row.product_name}}</li>
    </ul>
</div>

这是我的javascript

const appSearch = new Vue({
    el: "#SearchVueContenPage",
     data() {
        return {
            searchProduct: [], /*show this item only for search*/
            recentSearch: [], /*show this when page load or not searching*/
            q: ''
        }
      },
       methods: {

       },
        created() {
            fetch(ajax_appserver("public", "_api/searchProduct.php?fetch_api=true&getFromApp=vue&search="))
            .then(response => response.json())
            .then(json => {
                this.searchProduct = json.result;
                this.recentSearch = json.recent.slice(0, 3);
            });
        },
        computed: {
            filterSearchs: function(){
                return this.searchProduct.filter((row) => {
                    var query = this.q.toLowerCase();
                    return row.product_name.toLowerCase().indexOf(query)>-1 || row.business_name.toLowerCase().indexOf(query)>-1;
                });
            }
    }

});

最佳答案

您可以在计算属性中使用 filter 以仅返回与搜索查询匹配的项目,并使用条件语句测试是否已在搜索框中输入任何内容,如果没有,则返回最近的搜索结果。

const data = {
  "result": [{
      product_name: 'mike',
      business_name: 'student'
    },
    {
      product_name: 'beckham john',
      business_name: 'footballer'
    },
    {
      product_name: 'walcott',
      business_name: 'footballer'
    },
    {
      product_name: 'cech',
      business_name: 'footballer'
    },
    {
      product_name: 'jordan',
      business_name: 'actor'
    },
    {
      product_name: 'tom',
      business_name: 'actor'
    },
    {
      product_name: 'john',
      business_name: 'actor'
    }
  ],
  "recent": [{
      product_name: 'mike',
      business_name: 'student'
    },
    {
      product_name: 'beckham john',
      business_name: 'footballer'
    },
    {
      product_name: 'walcott',
      business_name: 'footballer'
    }
  ]
}


new Vue({
  el: '#app',
  data() {
    return {
      filter: '',
      items: null,
      loading: false
    }
  },
  computed: {
    search() {
      if (!this.items) {
        return []
      }

      if (!this.filter) {
        return this.items.recent
      }

      return this.items.result.filter(item => item.product_name.includes(this.filter) || item.business_name.includes(this.filter))
    }
  },
  mounted() {
    this.loading = true
    this.fetchData().then(() => {
      this.loading = false
    })
  },
  methods: {
    async fetchData() {
      // here will simulate an ansynchronous call using fetch
      //
      // an actual fetch call will look something like the following: 
      //
      // this.items = await fetch('/path/to/api').then(res => res.json()).then(json => json)
      
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          this.items = data
          resolve()
        }, 3000)
      })
    }
  },
  template: `
  <div id="wrapper">
    <label>Search</label>
    <input v-model="filter">
    <h4 v-if="loading" class="loading">Loading</h4>
    <h4 v-else>{{ !!filter ? 'Search Results' : 'Recent Search' }}</h4>
    <ul>
      <li v-for="(item, index) in search" :key="index">
        <p>Product Name: {{ item.product_name }}</p>
        <p>Business Name: {{ item.business_name }}</p>
      </li>
    </ul>
  </div>
  `
})
#wrapper {
  padding: 1rem 5rem;
  display: flex;
  flex-direction: column;
  background-color: rgba(179,229,252,1);
  
}

.loading:after {
  content: ' .';
  animation: dots 1s steps(5, end) infinite;}

@keyframes dots {
  0%, 20% {
    color: rgba(0,0,0,0);
    text-shadow:
      .25em 0 0 rgba(0,0,0,0),
      .5em 0 0 rgba(0,0,0,0);}
  40% {
    color: black;
    text-shadow:
      .25em 0 0 rgba(0,0,0,0),
      .5em 0 0 rgba(0,0,0,0);}
  60% {
    text-shadow:
      .25em 0 0 black,
      .5em 0 0 rgba(0,0,0,0);}
  80%, 100% {
    text-shadow:
      .25em 0 0 black,
      .5em 0 0 white;}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

关于javascript - 如何在使用vue js进行搜索时仅在键入时显示搜索结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53893399/

相关文章:

javascript - 试图理解看起来像 map 功能的对象的 Javascript 代码

javascript - 为什么 toLocaleString() 方法不起作用?

javascript - 没有 *.d.ts 的 JS 文件的 VS Code Intellisense

javascript - 谷歌缩放以适合该页面上的所有标记

javascript - 如何连接按钮并在 Vue JS 中使用其选项进行选择

javascript - Protractor - 使用过滤器定位表格元素

php - MySQL:过滤不同行中的多个值,但仅返回与两个值匹配的行

javascript - .双数组中的过滤器

javascript - jQuery offset() 被 body 位置打破 :relative combined with element margin

javascript - 为什么我的 Vue for 循环与 JSON 不起作用?