hookehuyr

fix(BrandModelPicker): 修复内容高度计算问题并优化滚动体验

动态计算品牌选择器内容区域高度,替代原有固定值
添加 catch-move 属性防止滚动冲突
增加底部内边距确保最后一个项目可见
添加错误处理机制和降级方案
......@@ -3,11 +3,11 @@
<!-- 品牌选择弹框 -->
<nut-popup v-model:visible="brandPickerVisible" position="bottom" :style="{ height: '80%' }">
<view class="brand-model-picker">
<view class="picker-header">
<view id="picker-header" class="picker-header">
<text class="picker-title">选择品牌型号</text>
<nut-button size="small" type="primary" @click="closePicker">关闭</nut-button>
</view>
<view class="search-container">
<view id="search-container" class="search-container">
<nut-searchbar
v-model="searchKeyword"
placeholder="搜索品牌名称"
......@@ -21,6 +21,7 @@
class="brand-content"
:scroll-y="true"
:style="{ height: contentHeight + 'rpx' }"
:catch-move="true"
ref="brandContentRef"
>
<view class="brand-list">
......@@ -68,8 +69,10 @@
</template>
<script setup>
import { ref, computed } from 'vue'
import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { Right } from '@nutui/icons-vue-taro'
import { $ } from '@tarojs/extend'
// 定义事件
const emit = defineEmits(['confirm', 'cancel'])
......@@ -210,11 +213,37 @@ const filteredBrands = computed(() => {
})
// 计算内容高度
const calculateContentHeight = () => {
// 弹框总高度 - 头部高度
const popupHeight = 1200 // rpx
const headerHeight = 120 // rpx (头部标题和按钮的高度)
contentHeight.value = popupHeight - headerHeight
const calculateContentHeight = async () => {
try {
// 获取窗口信息
const windowInfo = Taro.getWindowInfo()
const windowHeight = windowInfo.windowHeight
// 使用 setTimeout 确保 DOM 元素已渲染
setTimeout(async () => {
try {
// 获取弹框头部高度
const headerHeight = await $('.picker-header').height() || 120
// 获取搜索框高度
const searchHeight = await $('.search-container').height() || 100
// 计算可用高度:窗口高度的80% - 头部高度 - 搜索框高度 - 额外边距
const availableHeight = windowHeight * 0.8 - headerHeight - searchHeight - 40
// 转换为 rpx 单位 (假设设计稿宽度为750rpx)
const factor = 750 / windowInfo.windowWidth
contentHeight.value = Math.max(availableHeight * factor, 600) // 最小高度600rpx
} catch (error) {
console.warn('计算高度时出错,使用默认值:', error)
// 降级方案:使用相对安全的默认值
contentHeight.value = windowHeight * 0.5 * (750 / windowInfo.windowWidth)
}
}, 100)
} catch (error) {
console.warn('获取窗口信息失败,使用固定高度:', error)
// 完全降级方案:使用固定值
contentHeight.value = 800
}
}
// 显示品牌选择器
......@@ -268,6 +297,12 @@ const closeAllPickers = () => {
currentBrandModels.value = []
}
// 组件挂载时初始化
onMounted(() => {
// 初始化高度计算
calculateContentHeight()
})
// 暴露方法给父组件
defineExpose({
show,
......@@ -358,6 +393,7 @@ defineExpose({
.brand-list {
padding: 20rpx;
padding-bottom: 60rpx; /* 增加底部内边距,确保最后一个项目完全可见 */
.brand-item {
display: flex;
......