文章目錄
- 前言
- 一、功能概述
- 二、實現思路
- 三、代碼實現
- 總結
前言
Uniapp 實現微信小程序滑動面板功能詳解
一、功能概述
滑動面板是移動端常見的交互組件,通常用于在頁面底部展開內容面板。本文將介紹如何使用 Uniapp 開發一個支持手勢滑動的底部面板組件,實現以下核心功能:
觸摸滑動調整面板高度
邊界限制
與地圖組件的層級適配
二、實現思路
使用 Uniapp 框架實現跨平臺兼容
通過 CSS transform 實現動畫效果
基于微信小程序觸摸事件體系
結合選擇器 API 獲取元素尺寸
觸摸事件監聽:捕獲 touchstart/touchmove/touchend 事件
滑動距離計算:通過 clientY 坐標差值計算滑動距離
邊界限制:確保面板在允許的高度范圍內滑動
彈性動畫:使用 CSS transition 實現平滑過渡
層級管理:通過 z-index 控制與其他組件的層級關系
三、代碼實現
<template><viewclass="slider-panel"@touchstart="handleTouchStart"@touchmove.stop.prevent="handleTouchMove"@touchend="handleTouchEnd":style="{'min-height': `${initialPosition}px`,transform: `translateY(${translateY}px)`}"><view class="slider-panel-handle"></view><view class="slider-panel-content"><slot></slot></view></view>
</template>
<script>
export default {name: 'SliderPanel',props: {initialPosition: {type: Number,default: 100},deltaYThreshold: {type: Number,default: 100}},data() {return {isDragging: false,startY: 0,translateY: 0,panelHeight: 0,panelInitialShowHeight: 0}},async mounted() {const { height } = await this.getSelectorRect('.slider-panel-content')this.panelHeight = heightif (this.initialPosition > this.panelHeight) {this.panelInitialShowHeight = this.panelHeight} else {this.panelInitialShowHeight = height - this.initialPositionthis.translateY = this.panelInitialShowHeight}},methods: {getSelectorRect(selector) {const query = wx.createSelectorQuery().in(this)return new Promise((resolve) => {query.select(selector).boundingClientRect((rect) => {resolve(rect)}).exec()})},handleTouchStart(event) {const { clientY } = event.touches[0]this.isDragging = truethis.startY = clientY},handleTouchMove(event) {if (this.isDragging) {const { clientY } = event.touches[0]const deltaY = clientY - this.startYthis.startY = clientYthis.translateY += deltaYif (this.translateY < 0) {this.translateY = 0}if (this.translateY > this.panelInitialShowHeight) {this.translateY = this.panelInitialShowHeight}}},handleTouchEnd() {this.isDragging = false}}
}
</script><style scoped lang="scss">
.slider-panel {position: fixed;width: 100%;box-sizing: border-box;left: 0;bottom: 0;background: #fff;padding: 20rpx;border-radius: 24px 24px 0 0;box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);z-index: 30;will-change: transform;.slider-panel-handle {width: 60rpx;height: 6rpx;border-radius: 3rpx;background: #f0f0f0;margin: 16rpx auto 24rpx;}
}
</style>
<template><view class="container"><map style="width: 100%; height: 100%" :enable-scroll="false"></map><slider-panel><view v-for="item in 20" :key="item"><view class="item">{{ item }}</view></view></slider-panel></view>
</template>
<script>
import SliderPanel from '@/components/sliderPanel'
export default {components: {SliderPanel},data() {return {}},methods: {}
}
</script><style lang="scss">
page {height: 100%;width: 100%;
}
</style><style scoped lang="scss">
.container {position: relative;height: 100%;width: 100%;overflow: hidden;.item {display: flex;align-items: center;justify-content: center;border-bottom: 1px solid #ccc;height: 80rpx;}
}
</style>
總結
通過 Uniapp 開發滑動面板組件,可以有效實現跨平臺兼容。核心在于:
正確處理觸摸事件流
合理使用 CSS 動畫
精確控制滑動邊界
做好性能優化