2017-08-27 77 views
1

我有一个输入:VueJS 2个输入滤波器组

<input type="text" placeholder="filter by country name" />

,并列出清单:

<ul> 
 
    <li v-for="continent in continents"> 
 
    {{ continent[0].continent }} 
 
    <ul> 
 
     <li v-for="country of continent"> 
 
      {{ country.name }} ({{ country.callingCodes[0]}}) 
 
     </li> 
 
    </ul> 
 
    </li> 
 
</ul>

这是名单大陆和每一个是一个lis其中的国家。 如何实现搜索输入以仅显示我正在寻找的国家/地区? 我试图显示过滤国家的列表,但随后应用程序显示它们在每个大陆,而不是在适当的一个。

+0

你能分享一下你的json数据吗? –

+0

这是确切的答案=> https://restcountries.eu/rest/v2/all 我已经使用lodash(按分区域)对它进行了分组 并且您可以在代码中放置'subregion'而不是'continent' –

+0

https://codepen.io/blakewatson/pen/xEXApK - 这会给你一个想法 –

回答

2

首先,您需要从输入字段中获取字符串并将其用作搜索查询。这是通过v-model指令完成的,该指令可保持视图和数据同步。

所以,在你的模板:

<input type="search" v-model="query"> 

和模型:

data() { 
    return { 
    query: '', 
    countryList: [], // empty while data arrives 
    } 
} 

当我们加载数据,我们要去保持原来的列表中。我们还没有做任何事情。稍后我们将对其进行分组,同时我们也对其进行过滤。现在

xhr.onload = function() { 
    self.countryList = JSON.parse(xhr.responseText); 
}; 

,你要显示的大洲不只是_.groupBy倒是了 - 相反,他们也在过滤。此外,只要query也发生变化,就需要进行过滤。 a computed property的完美人选。

computed: { 
    continents() { 
    const filtered = this.countryList.filter(({name}) => { 
     return name.toLowerCase().includes(this.query.toLowerCase()) 
    }); 
    return _.groupBy(filtered, "subregion"); 
    }, 
}, 

现在我们只需要遍历这个计算的属性continents

<li v-for="subregion in continents"> 
    {{ subregion[0].subregion }} 
    <ul> 
     <li v-for="country of subregion"> 
      {{ country.name }} ({{ country.callingCodes[0]}})</label> 
     </li> 
    </ul> 
    </li> 
</ul> 
+0

是否与使用: 数据{ 查询:'', } ?因为它不会做任何事情。什么是适当的HTML? –

+0

据我所知,['data'必须是一个函数](https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function)。 –

+0

你的意思是“什么都不做”?如果在'input'字段旁边输入'{{query}}',则在键入时应该会看到数据更改。这在Vue的[非常简介](https://vuejs.org/v2/guide/index.html#Handling-User-Input)中有介绍。 –

2

这里有一种方法可以做到这一点。

基本上,将过滤器绑定到数据中的值,并根据计算值返回分组列表。

console.clear() 
 

 
new Vue({ 
 
    el: "#app", 
 
    data: { 
 
    countries: null, 
 
    countryFilter: null 
 
    }, 
 
    computed: { 
 
    continents() { 
 
     let filteredCountries = this.countries 
 
     let filter = c => c.name.toLowerCase().includes(this.countryFilter.toLowerCase()) 
 

 
     if (this.countryFilter) 
 
     filteredCountries = this.countries.filter(filter) 
 

 
     return _.groupBy(filteredCountries, "subregion") 
 
    } 
 
    }, 
 
    mounted() { 
 
    axios.get("https://restcountries.eu/rest/v2/all") 
 
     .then(response => this.countries = response.data) 
 
    } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script> 
 
<script src="https://unpkg.com/[email protected]"></script> 
 
<div id="app"> 
 
    <input v-model="countryFilter" type="text" placeholder="filter by country name" /> 
 
    <ul> 
 
    <li v-for="continent, name in continents"> 
 
     {{name}} 
 
     <ul> 
 
     <li v-for="country in continent">{{country.name}}</li> 
 
     </ul> 
 
    </li> 
 
    </ul> 
 
</div>

通常与Vue公司,执行上,你需要有反应的数据操作时,你会与计算性能做到这一点。