vue简单实现picker滑动选择器[思路为主], vue3 + vite
<template> <hr> <span>选中的值为: {{ renderColumns[selected]?.label }}</span> <hr> <div class="picker_container"> <div class="title_box"> <span>取消</span> <span>{{ title }}</span> <span>确定</span> </div> <div class="mask"></div> <div class="picker_box" @scroll="scroll" @scrollend="scrollend" ref="pickerRef" > <div class="item" v-for="(item, index) in renderColumns" :key="index" :class="item.id === selected ? 'current' : ''" >{{ item.label }}</div> </div> </div> </template> <script setup> import { reactive, toRefs, computed, ref, watch } from 'vue'; const state = reactive({ title: '测试', columns: [], // 选中项 selected: '' }) const { title, selected } = toRefs(state) const renderColumns = computed(() => { if (state.columns.length) { const empty = { label: '', id: '' } return [empty, ...state.columns, empty] } else { return [] } }) watch(() => state.columns.length, () => { if (state.columns.length) { state.selected = state.columns[0].id } }) setTimeout(() => { open() }, 10) function open() { state.columns = [{ label: '北京', id: 1 }, { label: '武汉', id: 2 }, { label: '深圳', id: 3 }, { label: '泰国', id: 4 }, { label: '新加坡', id: 5 }] } // 滚动事件 const pickerRef = ref() let timer = null function scroll(ev) { const scroll = pickerRef.value.scrollTop const index = Math.round(scroll / 60) state.selected = renderColumns.value[index + 1].id } function scrollend() { const scroll = pickerRef.value.scrollTop const index = Math.round(scroll / 60) state.selected = renderColumns.value[index + 1].id if (scroll / 60) { pickerRef.value.scrollTop = index * 60 } } </script> <style lang='scss' scoped > .picker_container { position: fixed; bottom: 0; left: 0; z-index: 1; width: 100%; height: 220px; .title_box { height: 40px; background-color: #999; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; span:nth-child(1) { color: #ccc; } span:nth-child(2) { color: #666; } span:nth-child(3) { color: #000; } } .mask { position: absolute; top: 100px; left: 0; height: 60px; width: 100%; z-index: 1; background-color: rgba(255, 192, 203, .3); mix-blend-mode: darken; } .picker_box { position: absolute; top: 40px; left: 0; height: 180px; width: 100%; overflow-y: scroll; scroll-behavior: smooth; z-index: 2; .item { height: 60px; display: flex; align-items: center; justify-content: center; transition: all .2s; } .item+.item { color: orange; } .current { font-weight: 600; font-size: 22px; color: #000 !important; &+.item { color: orange; } } } } hr { margin: 40px 0; } </style>
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!