Vue实现简单的移动端城市选择和搜索页面

页面展示

可实现模糊搜索,点击右侧导航栏跳到对应字母的位置等

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>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值