uni-app nvue 界面元素绑定的事件点击无效 发生v-if或是其他交互后事件全部失效点击没有反应
uni-app nvue 界面元素绑定的事件点击无效 发生v-if或是其他交互后事件全部失效点击没有反应
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Mac | 15.3 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Mac
HBuilderX类型:正式
HBuilderX版本号:4.66
手机系统:Android
手机系统版本号:Android 11
手机厂商:华为
手机机型:荣耀play
页面类型:nvue
vue版本:vue2
打包方式:云端
示例代码:
总共三个nvue文件:
c-list.nvue
c-modal.nvue
map.nvue
<template>
<view class="map-container">
<view style="flex:1;background:blue;"></view>
<!-- 真机再用map替换显示 不然模拟器很卡容易异常死机-->
<!-- <map style="flex:1"></map> -->
</view>
<!-- 全屏覆盖层 -->
<cover-view class="cover-view1">
<view class="view1">
<view class="btns" v-if="isShowBtns">
<view class="btn" >
<text class="btn" @click="tab(1)" :class="{'active1': activeIndex === 1}">普通</text>
</view>
<view class="btn" @click="tab(2)">
<text class="btn" :class="{'active2': activeIndex === 2}">卫星</text>
</view>
</view>
<view class="add-marker" v-else>
<text class="save-btn" @click="save()">保存</text>
<image class="marker" src="../../static/images/location.png"></image>
</view>
</view>
<view class="view2">
<image class="image" src="../../static/images/location.png" @click="getLocation()"></image>
<view class="camera-list" @click="openList1()">
<text class="camera-text">相机列表</text>
</view>
</view>
<view>
<c-model ref="model1" :dataList="dataList1" @clickItem="openList2"></c-model>
<c-model ref="model2" :dataList="dataList2" :isItemCloseModal="false"></c-model>
</view>
</cover-view>
</template>
<style lang="scss">
$border: 1px solid transparent;
$btnRedius: 40rpx;
.map-container{
flex: 1;
border: $border;
}
.cover-view1{
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 100rpx;
border: $border;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.view1{
border: $border;
height: 200px;
pointer-events: none; /* 允许点击穿透到下层 */
}
.btns {
display: flex;
flex-direction: row;
margin: 10px;
border-radius: $btnRedius;
background: #ccc;
}
.btn{
flex: 1;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 15px;
font-weight: bold;
border: $border;
}
.active1{
background: green;
border-top-left-radius: $btnRedius;
border-bottom-left-radius: $btnRedius;
}
.active2{
background: green;
border-top-right-radius: $btnRedius;
border-bottom-right-radius: $btnRedius;
}
.view2{
// flex: 1 等价于 100%,默认是column方向的100%;
// 可以通过改变方向row; 还有width:750rpx也是100%意思
height: 350rpx;
width: 750rpx;
border: $border;
pointer-events: auto; /* 子元素恢复点击 */
}
.image{
position: absolute;
width: 40px;
height: 40px;
bottom: 250rpx;
left: 20rpx;
}
.camera-list{
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding: 10px;
background: rgba(0,0,0,0.3);
}
.camera-text{
color: #fff;
}
.add-marker{
flex: 1;
display: flex;
align-items: center;
height: 200rpx;
}
.save-btn{
position: absolute;
top: 10px;
right: 10px;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
background: green;
color: #fff;
}
.marker{
width: 40px;
height: 40px;
top: 100px;
}
</style>
<template>
<view class="container">
<!-- 遮罩层(重新启用并优化) -->
<!-- <view
v-if="isShowModal && showModal"
class="mask"
@click="closeModal"
:style="{opacity: maskOpacity}"
></view> -->
<!-- 弹窗内容 -->
<view v-if="showModal">
<view
class="modal"
ref="animElement"
:style="{height: actualMaxHeight}"
>
<view class="modal-content">
<!-- 弹窗头部 -->
<view class="modal-header">
<view class="modal-title">
<text class="title" v-if="title">{{title}}</text>
</view>
<view class="close-wrapper" @click="closeModal">
<image
class="close"
src="../../static/images/close.png"
></image>
</view>
</view>
<!-- 可滚动内容区域 -->
<scroll-view class="scroll-list" scroll-y>
<c-list :dataList="dataList" @clickItem="clickItem"></c-list>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<template>
<scroll-view class="scroll-view" scroll-y="true">
<recycle-list
for="(item, i) in longList"
key-field="id"
style="width: 750rpx;"
>
<cell-slot scope="item">
<view class="item" @click="handleItemClick(item)">
<text class="item-text">{{item.name}}</text>
<text class="item-image">{{item.isChecked ? '✅' : '未选中'}}</text>
</view>
</cell-slot>
</recycle-list>
</scroll-view>
</template>
更多关于uni-app nvue 界面元素绑定的事件点击无效 发生v-if或是其他交互后事件全部失效点击没有反应的实战教程也可以访问 https://www.itying.com/category-93-b0.html
试一下别v-if隐藏view,通过透明度opacity来隐藏需要隐藏的view;
更多关于uni-app nvue 界面元素绑定的事件点击无效 发生v-if或是其他交互后事件全部失效点击没有反应的实战教程也可以访问 https://www.itying.com/category-93-b0.html
我尝试一下, 如果不行,我再用subNVue这种方式看看
opactiy 这种方式可以,但是毕竟占位置; 我把弹窗内容单独用subNVue这种方式实现了,然后原来的界面上元素v-if 交互的内容发现又可以点击了,事件又没有问题了;
自己摸索出来的方式
解决方式:
对于弹窗类的内容,用subNVue实现 这样理论上事件是完全隔离的
对于界面上元素v-if控制,界面简单的话,没啥问题,复杂的话我估计还是有这种问题的
(deepseek回答的是布局层级不能保证,导致事件触发错误或是不生效)
如果发现事件失效,尝试用opacity去控制交互,保证界面元素不丢失(这种的话理论上事件不会丢失绑定对象)
在nvue最好别使用v-if控制view的隐显,你可以简单测试一下,不断的显隐view控件,app的内存占用是不断叠加上升的;
这是一个典型的nvue页面事件绑定失效问题,主要原因是pointer-events属性的不当使用和cover-view在nvue中的特殊表现。
问题分析:
-
pointer-events冲突:在
.view1中设置了pointer-events: none,这会使其所有子元素(包括按钮)都无法响应点击事件。虽然.view2设置了pointer-events: auto,但.view1中的按钮点击仍然失效。 -
cover-view在nvue中的限制:nvue页面的cover-view与vue页面表现不同,事件绑定可能受到渲染层级影响。
-
v-if切换导致的事件丢失:当
isShowBtns状态变化时,DOM重新渲染可能造成事件绑定失效。
解决方案:
- 移除pointer-events限制:
.view1{
border: $border;
height: 200px;
/* 移除 pointer-events: none */
}
-
检查cover-view使用:确保所有需要交互的元素都在cover-view内,且没有层级遮挡。
-
优化v-if使用:考虑使用v-show替代v-if,避免DOM频繁销毁重建:
<view class="btns" v-show="isShowBtns">
<view class="add-marker" v-show="!isShowBtns">

