页面展示
可实现模糊搜索,点击右侧导航栏跳到对应字母的位置等
1.基本结构搭建及样式
比较简单,可以自行修改
<template>
<div class="home">
<!-- 头部 -->
<header class="header"></header>
<!-- 搜索栏 -->
<div class="search">
<input type="text" placeholder="输入关键字搜索" v-model="keyWord">
</div>
<div class="container">
<div class="container-left" id="box">
<!-- 热门城市 -->
<div class="hot-box">
<div v-for="city in hotCitys">{{ city.name }}</div>
</div>
<!-- 城市列表 -->
<section class="section" v-for="item in group" :id="item.groupName">
<div class="section-title">{{ item.groupName }}</div>
<div class="section-list">
<div class="item" v-for="city in item.groupList">{{ city.name }}</div>
</div>
</section>
</div>
<!-- 右侧导航栏 -->
<div class="container-right">
<div class="index">
<div class="index-item" v-for="item in indexs" @click="jump(item)">{{ item }}</div>
</div>
</div>
</div>
<!-- 展示搜索结果 -->
<div class="container" v-if="searchList.length" style="position: fixed;top: 88px;width: 100%;background-color: #ccc;">
<div class="container-left">
<section class="section">
<div class="section-list" v-for="city in searchList">
<div class="item">{{ city.name }}</div>
</div>
</section>
</div>
</div>
</div>
</template>
<style>
* {
margin: 0;
padding: 0;
}
body,
html,
.home,
#app {
height: 100%;
}
.home {
display: flex;
flex-direction: column;
}
.header {
height: 44px;
background-color: rgb(221, 221, 221);
}
.search {
height: 44px;
background-color: rgb(133, 105, 255);
}
.container {
display: flex;
flex: 1;
background-color: rgb(255, 255, 255);
overflow: hidden;
}
.container-left {
flex: 1;
overflow-y: auto;
position: relative;
}
.container-right {
width: 20px;
display: flex;
align-items: center;
}
.section-title {
padding-left: 20px;
height: 36px;
line-height: 36px;
background-color: #ccc;
}
.item {
padding-left: 20px;
height: 40px;
line-height: 40px;
border-bottom: 1px solid #ccc;
}
.index-item {
width: 20px;
height: 20px;
text-align: center;
cursor: pointer;
background-color: rgb(214, 189, 4);
}
</style>
2.js部分
<script>
export default {
name: 'HomeView',
data() {
return {
keyWord: "",//搜索关键字
//raw为城市数据内容的数组,可以使用自己的接口或者自己填写
raw: [
{
cityList: 110100,
name: '北京',
pinyin: 'beijing',
isHot: 1,
},
{
cityList: 110100,
name: '北海',
pinyin: 'beihai',
},
{
cityList: 120100,
name: '天津',
pinyin: 'tianjin',
},
{
cityList: 130100,
name: '石家庄',
pinyin: 'shijiazhang',
},
{
cityList: 110100,
name: '大理',
pinyin: 'dali',
},
{
cityList: 110100,
name: '拉萨',
pinyin: 'lasa',
},
{
cityList: 120100,
name: '曼岛',
pinyin: 'mandao',
},
{
cityList: 130100,
name: '百慕大',
pinyin: 'baimuda',
},
{
cityList: 110100,
name: '驻马店',
pinyin: 'zhumadian',
},
{
cityList: 110100,
name: '南京',
pinyin: 'nanjing',
},
{
cityList: 120100,
name: '重庆',
pinyin: 'chongqing',
},
{
cityList: 130100,
name: '厦门',
pinyin: 'xiamen',
},
{
cityList: 130100,
name: '深圳',
pinyin: 'shenzhen',
isHot: 1,
},
{
cityList: 130100,
name: '泉州',
pinyin: 'quanzhou',
isHot: 1,
},
{
cityList: 130100,
name: '杭州',
pinyin: 'hangzhou',
isHot: 1,
},
{
cityList: 130100,
name: '广州',
pinyin: 'guangzhou',
isHot: 1,
},
{
cityList: 130100,
name: '香洲',
pinyin: 'xiangzhou',
isHot: 1,
},
{
cityList: 130100,
name: '雷州',
pinyin: 'leizhou',
isHot: 1,
},
{
cityList: 130100,
name: '赣州',
pinyin: 'ganzhou',
isHot: 1,
},
{
cityList: 130100,
name: '明日方州',
pinyin: 'mingrifangzhou',
isHot: 1,
},
]
}
},
computed: {
group() {
let result = []
// 遍历raw
this.raw.forEach(city => {
// 获取pinyin首字母
const groupName = city.pinyin[0].toUpperCase()
// 获取raw数组内所有pinyin的首字母
const index = result.findIndex(item => item.groupName === groupName)
// 判断index是否为空
if (index > -1) {
result[index].groupList.push(city)
} else {
// 把首字母放到数组里面
result.push({
groupName: groupName,
groupList: [city]
})
}
});
return result.sort((a, b) => {
// return a.groupName - b.groupName ? 1 : -1;
return a.groupName.charCodeAt(0) - b.groupName.charCodeAt(0);
});
},
indexs() {
return this.group.map((item) => item.groupName)
},
hotCitys() {
return this.raw.filter((item) => item.isHot === 1)
},
// 搜索结果,依赖项:keyWord,raw
searchList() {
// 精准搜索
// return this.raw.filter((item) => item.name === this.keyWord)
// 模糊搜索
if (!this.keyWord) return []
return this.raw.filter((item) => item.name.includes(this.keyWord))
// 等价于
// if (!this.keyWord) {
// return [];
// } else {
// return this.raw.filter((item) => item.name.includes(this.keyWord))
// }
},
},
methods: {
//点击右侧导航栏,跳到对应字母的位置
jump(data) {
// 根据data找到对应id
const dom = document.querySelector(`#${data}`)
// 计算该dom距离顶部的距离
const offsetTop = dom.offsetTop;
// 修改滚动元素的scrollTop值
document.querySelector('#box').scrollTop = offsetTop;
}
}
}
</script>