当前位置: 首页 > web >正文

UNiAPP地区选择

<template>
  <view class="container">
    <!-- 左侧地区列表 -->
    <scroll-view
      class="left-list"
      scroll-y
      :scroll-into-view="currentLetterId"
      scroll-with-animation
      @scroll="onScroll"
      ref="scrollView"
    >
      <view
        v-for="group in dataList"
        :key="group.letter"
        :id="'letter-' + group.letter"
        class="group"
        :data-letter="group.letter"
      >
        <view class="group-letter">{{ group.letter }}</view>
        <view style="display: flex; gap: 20rpx; padding: 20rpx;">
                    <view v-for="item in group.items" :key="item" class="item">{{ item }}</view>
                </view>
      </view>
    </scroll-view>

    <!-- 右侧字母索引 -->
    <view
      class="right-index"
      @touchstart.prevent="onTouchStart"
      @touchmove.prevent="onTouchMove"
      @touchend.prevent="onTouchEnd"
      ref="indexWrapper"
    >
      <view
        v-for="(letter, index) in letters"
        :key="letter"
        class="letter"
        :class="{ active: letter === activeLetter }"
        :data-index="index"
      >
        {{ letter }}
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      letters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),
      dataList: [
        { letter: 'A', items: ['安庆', '鞍山', '安阳'] },
        { letter: 'B', items: ['北京', '保定', '包头'] },
        { letter: 'C', items: ['长沙', '成都', '重庆'] },
        { letter: 'D', items: ['大连', '东莞', '德阳'] },
        { letter: 'F', items: ['福州', '佛山'] },
        { letter: 'G', items: ['广州', '贵阳'] },
        { letter: 'H', items: ['杭州', '合肥', '哈尔滨'] },
        { letter: 'J', items: ['济南', '嘉兴'] },
        { letter: 'K', items: ['昆明'] },
        { letter: 'L', items: ['兰州', '洛阳'] },
        { letter: 'M', items: ['绵阳'] },
        { letter: 'N', items: ['南京', '南昌'] },
        { letter: 'Q', items: ['青岛', '泉州'] },
        { letter: 'S', items: ['上海', '苏州', '深圳'] },
        { letter: 'T', items: ['天津', '唐山'] },
        { letter: 'W', items: ['武汉', '无锡'] },
        { letter: 'X', items: ['厦门', '西安'] },
        { letter: 'Y', items: ['烟台', '宜昌'] },
        { letter: 'Z', items: ['郑州', '珠海'] }
      ],
      currentLetterId: '',
      activeLetter: '',
      indexItemHeight: 0,
      indexTop: 0,
    };
  },
  mounted() {
    // 获取右侧字母索引容器的位置和单个字母高度
    uni.createSelectorQuery()
      .select('.right-index')
      .boundingClientRect(rect => {
                console.log('打印高度')
                console.log(rect)
        this.indexTop = rect.top;
      })
      .exec();
            // 获取每个字母的高度
            this.$nextTick(() => {
                const letterHeights = [];
                this.letters.forEach((letter, index) => {
                    uni.createSelectorQuery()
                        .select(`.right-index .letter:nth-child(${index + 1})`)
                        .boundingClientRect(rect => {
                            letterHeights.push(rect.height);
                            // 当所有字母的高度都获取到后,计算平均高度
                            if (letterHeights.length === this.letters.length) {
                                this.indexItemHeight = letterHeights.reduce((a, b) => a + b, 0) / letterHeights.length;
                                console.log('字母高度')
                                console.log(this.indexItemHeight)
                            }
                        })
                        .exec();
                });
            });
  },
  methods: {
    scrollToLetter(letter) {
      this.currentLetterId = 'letter-' + letter;
      this.activeLetter = letter;
    },
    onTouchStart(e) {
      this.handleTouch(e);
    },
    onTouchMove(e) {
      this.handleTouch(e);
    },
    onTouchEnd() {
      // 触摸结束可以做一些清理操作,如果需要
    },
    handleTouch(e) {
      const touch = e.touches[0];
      const y = touch.clientY;
      // 计算触摸点相对于字母索引顶部的偏移
      let index = Math.floor((y - this.indexTop) / this.indexItemHeight);
      if (index < 0) index = 0;
      if (index >= this.letters.length) index = this.letters.length - 1;
      const letter = this.letters[index];
      if (letter && letter !== this.activeLetter) {
        this.scrollToLetter(letter);
      }
    },
    onScroll(e) {
      // 可选:根据滚动位置动态改变右侧高亮字母
      // 这里可以实现滚动联动右侧字母高亮,稍复杂,可根据需求添加
    }
  }
};
</script>

<style>
.container {
  display: flex;
  height: 100vh;
    background-color: #fff;
}
.left-list {
  flex: 1;
}
.group {
  padding: 20rpx 0;
}
.group-letter {
  font-weight: bold;
  font-size: 36rpx;
  background: #F2F4F5;
  padding: 10rpx 30rpx;
}
.item {
    width: 120rpx;
    height: 42rpx;
    line-height: 42rpx;
    background-color: #F2F4F5;
    text-align: center;
    border-radius: 30rpx;
    font-size: 24rpx;
}
.right-index {
  width: 60rpx;
  background: transparent;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  user-select: none;
  /* 方便触摸 */
  padding: 10rpx 0;
}
.letter {
  font-size: 28rpx;
  color: #666;
  padding: 4rpx 0;
  width: 100%;
  text-align: center;
  cursor: pointer;
}
.letter.active {
  color: #007AFF;
  font-weight: bold;
}
/* 通用隐藏方案 */
::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
  -webkit-appearance: none;
  background: transparent;
}

/* 安卓专用优化 */
/* #ifdef APP-PLUS */
scroll-view ::-webkit-scrollbar {
  display: none;
}
/* #endif */
</style>

最后效果,可以根据需要调试

http://www.xdnf.cn/news/6678.html

相关文章:

  • 解码国际数字影像产业园:成都高品质办公楼宇
  • OpenCV阈值处理完全指南:从基础到高级应用
  • 5G行业专网部署费用详解:投资回报如何最大化?
  • Zephyr OS Nordic芯片的Flash 操作
  • 提权脚本Powerup命令备忘单
  • 从小区到商场再到校园,AI智能分析网关V4高空抛物检测方案全场景护航
  • Spring Boot 封装 MinIO 工具
  • DDS(数据分发服务) 和 P2P(点对点网络) 的详细对比
  • [QMT量化交易小白入门]-五十四、核心资产ETF轮动目前年化只有74%了,在过滤掉当天止损,当天买入的之后
  • Java 21 + Spring Boot 3.5:AI驱动的高性能框架实战
  • require/exports 或 import/export的联系和区别,各自的使用场景
  • 基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
  • Expo项目在本地打包apk的问题
  • Vue主题色切换实现方案(CSS 变量 + 类名切换)
  • 【前端】[vue3] [uni-app]使用 vantUI 框架
  • 使用 OpenCV 将图像中标记特定颜色区域
  • 黑马k8s(九)
  • day 26
  • Python训练营打卡 Day27
  • Java 中使用 Redis 实现消息订阅/发布
  • 三极管知识
  • 根据台账批量制作个人表
  • 5G-A和未来6G技术下的操作系统与移动设备变革:云端化与轻量化的发展趋势
  • 【Pandas】pandas DataFrame kurt
  • 如何让 Google 收录 Github Pages 个人博客
  • go封装将所有数字类型转浮点型,可设置保留几位小数
  • AG-UI 协议:重构多模态交互,开启智能应用新纪元
  • C42-作业练习
  • 光谱相机的空间分辨率和时间分辨率
  • MinIO 开源的分布式文件服务器