fix(ui): 修复搜索栏背景色和弹窗嵌套导致的层级问题
- 为搜索栏添加白色背景,避免在深色模式下显示异常 - 将 SchemeA 组件中的行业选择器弹窗提升到外层,避免嵌套弹窗在真机上的层级冲突 - 更新 lessons-learned 文档,记录弹窗嵌套问题的解决方案
Showing
3 changed files
with
61 additions
and
6 deletions
| ... | @@ -178,12 +178,62 @@ setTimeout(() => { | ... | @@ -178,12 +178,62 @@ setTimeout(() => { |
| 178 | <IconFont :name="iconName" :key="iconName" /> | 178 | <IconFont :name="iconName" :key="iconName" /> |
| 179 | ``` | 179 | ``` |
| 180 | 180 | ||
| 181 | +### ❌ 坑 3: 嵌套 nut-popup 导致真机层级冲突 | ||
| 182 | + | ||
| 183 | +**问题描述**: | ||
| 184 | +```vue | ||
| 185 | +<!-- ❌ 真机测试时,内层弹窗被外层弹窗的底部按钮遮挡 --> | ||
| 186 | +<PlanPopup title="申请计划书"> | ||
| 187 | + <!-- 表单内容 --> | ||
| 188 | + | ||
| 189 | + <!-- 嵌套的弹窗 --> | ||
| 190 | + <nut-popup position="bottom" v-model:visible="showIndustryPicker"> | ||
| 191 | + <nut-picker :columns="industryColumns" /> | ||
| 192 | + </nut-popup> | ||
| 193 | +</PlanPopup> | ||
| 194 | +``` | ||
| 195 | + | ||
| 196 | +**场景**: SchemeA 组件使用 PlanPopup 容器(外层 nut-popup),内部再嵌套一个行业选择器(内层 nut-popup) | ||
| 197 | + | ||
| 198 | +**原因**: | ||
| 199 | +1. **小程序渲染机制**: 微信小程序的双线程渲染导致嵌套弹窗的层级处理异常 | ||
| 200 | +2. **渲染上下文**: 外层 `nut-popup` 创建了独立的渲染上下文,内层即使设置更高 `z-index` 也可能被遮挡 | ||
| 201 | +3. **DOM 顺序**: 外层弹窗的底部按钮在 DOM 中位于内层弹窗之后,真机渲染时可能覆盖 | ||
| 202 | + | ||
| 203 | +**解决方案**: 将内层弹窗提升到外层弹窗外部 | ||
| 204 | +```vue | ||
| 205 | +<!-- ✅ 正确:弹窗并列,不嵌套 --> | ||
| 206 | +<PlanPopup title="申请计划书"> | ||
| 207 | + <!-- 表单内容 --> | ||
| 208 | +</PlanPopup> | ||
| 209 | + | ||
| 210 | +<!-- 内层弹窗提升到外层,设置更高的 z-index --> | ||
| 211 | +<nut-popup | ||
| 212 | + position="bottom" | ||
| 213 | + v-model:visible="showIndustryPicker" | ||
| 214 | + :z-index="9999" | ||
| 215 | + :overlay="true" | ||
| 216 | +> | ||
| 217 | + <nut-picker :columns="industryColumns" /> | ||
| 218 | +</nut-popup> | ||
| 219 | +``` | ||
| 220 | + | ||
| 221 | +**关键点**: | ||
| 222 | +- ✅ 将内层 `nut-popup` 移到外层组件外部 | ||
| 223 | +- ✅ 设置 `:z-index="9999"` 确保显示在最上层 | ||
| 224 | +- ✅ 保持 DOM 顺序:外层弹窗 → 内层弹窗(后渲染的在上层) | ||
| 225 | + | ||
| 226 | +**适用场景**: | ||
| 227 | +- 任何需要在 `nut-popup` 内部再使用 `nut-popup` 的情况 | ||
| 228 | +- 特别是选择器(Picker)、对话框(Dialog)等弹窗组件 | ||
| 229 | + | ||
| 181 | ### ✅ NutUI 最佳实践 | 230 | ### ✅ NutUI 最佳实践 |
| 182 | 231 | ||
| 183 | 1. **优先使用原生组件**: 当 NutUI 组件样式限制时 | 232 | 1. **优先使用原生组件**: 当 NutUI 组件样式限制时 |
| 184 | 2. **添加 key 属性**: 动态切换图标时 | 233 | 2. **添加 key 属性**: 动态切换图标时 |
| 185 | -3. **深度样式覆盖**: 尝试 `:deep()` 选择器 | 234 | +3. **避免嵌套弹窗**: 始终将内层弹窗提升到外层外部 |
| 186 | -4. **查阅文档**: 确认 NutUI 版本和已知问题 | 235 | +4. **深度样式覆盖**: 尝试 `:deep()` 选择器 |
| 236 | +5. **查阅文档**: 确认 NutUI 版本和已知问题 | ||
| 187 | 237 | ||
| 188 | --- | 238 | --- |
| 189 | 239 | ... | ... |
| ... | @@ -95,9 +95,15 @@ | ... | @@ -95,9 +95,15 @@ |
| 95 | /> | 95 | /> |
| 96 | <span class="text-sm text-gray-500 shrink-0 ml-2 mr-5">%</span> | 96 | <span class="text-sm text-gray-500 shrink-0 ml-2 mr-5">%</span> |
| 97 | </div> | 97 | </div> |
| 98 | + </PlanPopup> | ||
| 98 | 99 | ||
| 99 | - <!-- Industry Picker --> | 100 | + <!-- Industry Picker - 提升到 PlanPopup 外部,避免嵌套弹窗导致的层级问题 --> |
| 100 | - <nut-popup position="bottom" v-model:visible="showIndustryPicker"> | 101 | + <nut-popup |
| 102 | + position="bottom" | ||
| 103 | + v-model:visible="showIndustryPicker" | ||
| 104 | + :z-index="9999" | ||
| 105 | + :overlay="true" | ||
| 106 | + > | ||
| 101 | <nut-picker | 107 | <nut-picker |
| 102 | :columns="industryColumns" | 108 | :columns="industryColumns" |
| 103 | title="选择行业" | 109 | title="选择行业" |
| ... | @@ -105,7 +111,6 @@ | ... | @@ -105,7 +111,6 @@ |
| 105 | @cancel="showIndustryPicker = false" | 111 | @cancel="showIndustryPicker = false" |
| 106 | /> | 112 | /> |
| 107 | </nut-popup> | 113 | </nut-popup> |
| 108 | - </PlanPopup> | ||
| 109 | </template> | 114 | </template> |
| 110 | 115 | ||
| 111 | <script setup> | 116 | <script setup> | ... | ... |
| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | <NavHeader title="我的计划书" /> | 9 | <NavHeader title="我的计划书" /> |
| 10 | 10 | ||
| 11 | <!-- Search Bar --> | 11 | <!-- Search Bar --> |
| 12 | - <view class="px-[24rpx] py-[16rpx]"> | 12 | + <view class="px-[24rpx] py-[16rpx] bg-white"> |
| 13 | <SearchBar | 13 | <SearchBar |
| 14 | v-model="searchValue" | 14 | v-model="searchValue" |
| 15 | placeholder="搜索计划书名称、客户姓名..." | 15 | placeholder="搜索计划书名称、客户姓名..." | ... | ... |
-
Please register or login to post a comment