1***@qq.com
1***@qq.com
  • 发布:2026-09-16 17:02
  • 更新:2026-09-16 17:04
  • 阅读:28

【报Bug】scroll-view在微信小程序,uni-app Vue3 小程序事件代理/编译映射异常,滚动的时候误触发子组件事件

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Mac

PC开发环境操作系统版本号: 26.5.1

第三方开发者工具版本号: 2.01.2510290

基础库版本号: 3.17.2

项目创建方式: CLI

CLI版本号: 3.0.0-4000820240401001

示例代码:
      <movable-view class="drag-view" direction="vertical" :disabled="loading" :out-of-bounds="true" :damping="50" @change="dragChange">  
        <view class="drag-tip down">{{ deltaY ? '松开后进入上一分类' : '下拉进入上一分类' }}</view>  
        <scroll-view  
          v-if="categoryTree.length"  
          class="scroll-list"  
          :scroll-y="isNext && !disableScroll && !showCreditBuyRulesPopup"  
          :scroll-into-view="scrollViewId"  
          :lower-threshold="300"  
          @touchstart="touchStart"  
          @touchend="clearControl"  
          @scroll="onScroll"  
          @scrolltolower="loadmore"  
        >  
          <view id="base-line" />  
          <view v-if="currentCategory.loadover && !currentCategory.list.length" class="empty-wrapper">  
            <HcNoData no-data="暂无商品" :btn-show="false" />  
          </view>  
          <view v-else class="wrapper">  
            <view v-show="currentCategory.code === '20'" class="credit-buy-tip flex" @click="showCreditBuyRulesPopup = true">  
              【先买后付】收货{{ accountPeriod }}天后再付款<image class="icon" src="@/static/svg/question-o.svg" />  
            </view>  
            <view  
              v-for="(goods, index) in currentCategory.list"  
              :key="`${goods.skuCode}-${index}`"  
              class="goods-wrapper"  
              :style="goods.height ? `height: ${goods.height}px` : ''"  
            >  
              <!-- props 回调:避免页面 @自定义事件被 scroll 误调;虚拟列表裁剪见 isShowGoods -->  
              <hc-goods-card  
                v-if="isShowGoods(goods)"  
                :goods="{ ...goods, operationInfo: currentOperation }"  
                :quantityList="cartSkuQuantity.quantityList"  
                :liveSkuMap="liveSkuMap"  
                :secKillInfo="goods.secKillInfo"  
                :first="index === 0"  
                origin="分类"  
                size="100"  
                @leaveTrack="leaveTrack"  
                @addGoods="addGoods"  
                @showBusinessPopup="showBusinessPopup"  
              />  
            </view>  
          </view>  
          <view v-show="currentCategory.list.length" class="loadtext flex">  
            <text :class="['text', { show: !offsetY }]">{{ loadtext }}</text>  
          </view>  
        </scroll-view>  
        <view class="drag-tip up">{{ deltaY ? '松开后进入下一分类' : '上拉进入下一分类' }}</view>  
      </movable-view>  
    </movable-area>

操作步骤:

在微信小程序上下滚动内容区域,就会自动调用组件上的@相关的事件,scroll-view如果有dom增减更加明显,比如头部加个sticky或者v-if动态判断

预期结果:

不自动调用组件事件

实际结果:

自动调用了不该调用的子组件事件

bug描述:

使用scroll-view的时候,内部子组件如果绑定了@事件,在滚动的时候会被误触发,把事件通过props :eventaxxx="funca",则不会被误触。

2026-09-16 17:02 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

感谢您的反馈。针对您提交的关于 scroll-view 在微信小程序中滚动时误触发子组件事件的 Bug,官方评审意见如下:

1. Bug 反馈内容完整性分析

  • BUG 描述:描述较为清晰,明确指出了在 scroll-view 滚动时会误触发内部子组件绑定的 @ 事件,且发现通过 props 传递回调函数可以规避此问题。这为排查编译层的事件代理/映射问题提供了有用的线索。
  • 代码示例:代码片段展示了 movable-areamovable-viewscroll-view 嵌套的复杂场景,并包含了虚拟列表(v-if="isShowGoods(goods)")和动态判断逻辑。但该代码片段并非完整可独立运行的工程,其中包含大量未定义的变量和方法(如 isFirstCategorydragStylecategoryTreecurrentCategory 等)。官方在处理此类编译事件错位问题时,通常需要一个最小化且可直接复现的完整示例,建议您能够补充一个精简的、去除业务逻辑后仍能触发该问题的可运行代码。
  • 复现步骤:复现步骤描述了“上下滚动内容区域就会自动调用组件上的 @ 相关事件”,并提到“如果有 DOM 增减更加明显”。虽然现象清楚,但缺少对具体滚动速度、手势力度以及是否伴随特定 DOM 增减动作的详细描述。由于无法识别附件,如果您有相关复现视频,建议转化为更详细的文字描述(例如:快速滑动还是慢速滑动触发、具体触发了哪个事件等)。
  • 预期结果与实际结果:预期和实际结果描述合理,符合 Bug 反馈规范。
  • 分类信息:包含了 PC 开发环境、HBuilderX 版本(正式版)、目标平台(微信小程序)以及 Vue3 环境。信息基本完整,但建议补充微信开发者工具的版本号以及微信基础库版本号,以便更精准地定位问题。

2. Bug 是否成立及分析

从知识库和历史社区反馈来看,您描述的现象在 uni-app Vue3 项目的小程序端是有相关记录的。在 DCloud问答_148599 中,就有开发者反馈了 Vue3 在 scroll-view 中快速滚动会触发子节点 click 事件的问题,该问题在 iOS 小程序端尤为明显。

结合官方文档关于 scroll-viewmovable-view 的说明,产生这种现象的可能原因有以下几个方面:

  1. Vue3 事件编译机制差异:Vue3 在小程序端的事件代理和编译映射机制与 Vue2 存在差异。在快速滚动或 DOM 动态增减时,可能会导致事件绑定与真实触发的 DOM 节点之间出现偏移或错位,从而误触发经过映射的子组件 @ 事件。
  2. scroll-viewmovable-view 嵌套冲突:官方文档明确指出,movable-view 必须在 movable-area 组件中且必须是直接子节点。scroll-viewmovable-view 都涉及对手势事件的处理,两者嵌套使用时极易产生手势冲突。在滑动过程中,事件流在原生组件和逻辑层之间的传递可能会出现异常。
  3. 虚拟列表 DOM 复用:您的代码中使用了类似虚拟列表的机制(v-if="isShowGoods(goods)" 和动态 height)。在滚动过程中,DOM 节点的大量销毁和重建如果与事件代理的更新时机不匹配,很容易导致事件误触发。

当前结论:该 Bug 反映的现象有依据,但由于涉及复杂的组件嵌套和 Vue3 编译机制,需要进一步确认是框架编译层的缺陷还是特定复杂场景下的组件冲突。

3. 建议

在官方进一步排查并修复该问题前,您可以尝试以下方案进行规避:

  • 延续您的 Props 回调方案:您提到的“把事件通过 props :eventaxxx="funca 传递,则不会被误触”是一个有效的规避策略。这是因为通过 props 传递的函数不经过 Vue3 的小程序事件代理编译映射机制,而是直接在组件实例上调用,从而避开了事件错位的问题。
  • 避免 scroll-view 直接嵌套在 movable-view:如果业务允许,尝试解耦 movable-viewscroll-view 的嵌套关系,或者使用其他方式实现下拉/上拉分类切换效果,以减少原生手势事件的冲突。
  • 优化虚拟列表实现:如果列表较长,建议使用插件市场成熟的虚拟列表组件(搜索 虚拟列表),它们在 DOM 复用和事件绑定上处理得更完善,可以减少因 DOM 频繁增减导致的事件错乱。

建议您在后续补充一个最小可复现的完整代码示例,以便官方研发团队更精准地定位和修复 Vue3 事件编译映射的问题。

内容为 AI 生成,仅供参考

要回复问题请先登录注册