1、目标效果
具体代码在下面,全部写在App.vue中,复制粘贴即可运行
2、原理分析
(1)准备一个对象数组,类似于这样 [ {title: 'B', name: '北京'} ],确定好分组依据
(2)将对象数组的分组操作放在computed中执行
(3)如何分组?对数组进行遍历(for循环、foreach),在循环里创建一个空对象,将符合条件的值添加到对象里面,最终返回一个对象,key值为组名,value为多条数据的数组
(4)list.reduce((accumulator, item)=>{}, {}) ,reuce有两个参数,第一个参数传回调函数用于累加,第二个参数是累加结果的初始值,由于我们最后要拼接成一个对象,所以初始值为{}空对象;回调函数的第一个参数是累加器,它与reduce第二个参数类型相同,回调函数第二个值就是数组中的每一项,总的来说,reduce就是通过累加器与当前值执行一些操作,返回一个新的累加结果,可以将一个数组转成对象呦!
3、具体代码
<template>
<div id="app">
<el-input placeholder="请输入搜索条件" style="width:300px;" v-model="searchInput"></el-input>
<dl v-for="(item, key, index) in searchList" :key="index">
<dt>{{ key }}</dt>
<dd v-for="(i,j) in item" :key="j">{{ i.name }}</dd>
</dl>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
searchInput: '', // 搜索条件
lists:[ // 对象数组
{title: 'B', name: '北京'},
{title: 'B', name: '保定'},
{title: 'B', name: '北海'},
{title: 'C', name: '长春'},
{title: 'C', name: '常德'},
{title: 'A', name: '安庆'},
{title: 'D', name: '大庆'},
{title: 'D', name: '东莞'},
{title: 'F', name: '福州'},
{title: 'F', name: '抚州'},
]
}
},
computed:{
// 将对象数组进行分组(方法一:foreach)
list(){
let groups = {}
this.lists.forEach(item=>{
// item为对象数组中的每个对象,此处根据title进行分组
// value为组名
let value = item['title'];
// 新对象groups判断有无相对应组名,有则保留,否则为空数组
groups[value] = groups[value] || [];
// 向这个组插入数据
groups[value].push(item)
})
// 返回这个经过分组过后的对象
return groups
},
// 将对象数组进行分组(方法二:reduce)
list2(){
// rv为累加器,current为对象数组中的每一项即是一个对象
return this.lists.reduce((rv,current)=>{
(rv[current['title']]=rv[current['title']]||[]).push(current)
return rv
},{})
},
// 搜索分组
searchList(){
let obj = {}
// citys为上面对象数组经过分组过后的数据
let citys = this.list;
if(this.searchInput == ''){
// 搜索为空,则返回初始分组后的数据
return this.list
}else{
// 搜索不为空,通过for in 对 对象进行遍历
for (let key in citys) {
// key为组名,citys[key] 为组名下的多个数据,即城市列表,城市列表下的城市名与搜索条件进行比较,然后筛选出能够找到的城市
let searchResult = citys[key].filter( item=>{
return item.name.indexOf(this.searchInput) != -1
})
// 搜索到目标结果,则返回相对应拼接后的对象
if(searchResult.length > 0){
obj[key] = searchResult
return obj
}
}
}
}
}
}
</script>
<style>
#app {
text-align: center;
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 16px;
}
</style>