
字节笔记本
2026年10月7日 · 约 6 分钟读完
停止要写在图标外面
价格区域是一层 view,点击时进入商品详情。里面的编辑图标又要单独打开改价。图标上写了 stop,点图标仍然会进到外层。停在组件标签上,挡不住从组件内部冒出来、再落到父级上的那一次点击。

两层点击各做一件事
外层是 class="pricetext",监听 @click.prevent,调用 goproductDetails,参数是当前这项 p。文案是参考价格,金额来自 formatAmount(p.price)。有 customPrice 时再显示自定义价格,金额用 formatAmount(p.customPrice)。图标是 u-icon,name 为 edit-pen,颜色 #2979ff,尺寸 20,左边距 15 像素。图标的监听是 @click.stop,调用 openEditPrice(p, item)。
prevent 在外层,阻止的是这一层点击的默认行为,不是子节点的冒泡。stop 写在图标组件上。组件内部若还有真正接点击的节点,那次点击从内部节点往上走,可以先到达外层 view,而不必先被组件标签上的修饰符吃掉。于是详情和改价一起发生。用户看到的就是:加了 stop 仍然触发上面的事件。
三种改法里,外面包一层最稳
第一种在图标外包一层 view,这层写 @click.stop,图标自己的监听改成 @click,不再把 stop 放在组件上。内部点击先进入这层原生节点,在这里停下,到不了价格那一层。详情不会被打开。改价仍由图标的监听调用。
第二种不包节点,改成函数接收事件,调用 stopPropagation,再调用 openEditPrice。这要求事件对象真的传到这个函数。若组件没有把内部点击的事件对象交出来,函数里的停止没有对象可调。样本在这一段把参考价格的金额错写成了 p.customPrice。原模板的参考价格用的是 p.price。只为了阻止冒泡时,不要把金额字段一起换掉。自定义价格仍留在原来的 v-if 里。
第三种把图标改成 @tap.stop。这段对话写明是在考虑 uni-app。有的端上点击和触摸不是同一条冒泡。若项目里列表用的是点击,只改图标为触摸,可能变成两套事件,停止对不上外层。外层若仍是 @click,优先让内外使用同一种事件,再在原生包装上停止。

先确认停住的是哪一层
点图标时只应改价。点价格文字时才进详情。包装层的停止放在图标外侧、价格区域内侧。不要在改监听时把 formatAmount 的字段从 price 改成 customPrice。图标的颜色、尺寸和左边距与冒泡无关,可以不动。若包装之后仍然双触发,再查是否还有别的监听写在更外层,而不是再给组件标签加一个 stop。
外层的 prevent 只影响价格这一层点击的默认动作。它不会让子节点的点击停在半路。图标是一个组件。组件标签上的 stop,停的是挂在组件上的那一次监听。组件内部如果还有节点发出点击,事件沿父链向上,父链上最近的原生容器就是价格那一层。于是详情函数和改价函数都会跑。用户的现象是加了停止仍然打开详情。
外包一层原生容器之后,内部点击先进入这层。这层的停止让事件不再向上。价格那一层收不到这次点击,详情不会打开。改价仍写在图标上,并且不要再带停止,避免和图标内部的实现抢同一次事件。第二种把停止写进函数,前提是事件对象真的作为参数进来。组件若吞掉了事件对象,函数第一行就没有可调用的方法。
第二种样本把参考价格的金额错写成自定义价格的字段。原界面是参考价格读价格,自定义价格在条件里另读。修正冒泡时把这行改回去。否则没有自定义价格的项会显示空的参考价,问题看起来像数据丢了,其实是示例抄错字段。第三种换成触摸事件时,外层也要一起换,或确认这一端上触摸和点击会合成同一次。只改图标、不改外层,停止的是另一条事件。
价格区域的点击进入详情,图标的点击只改价。一次手指若进了两个函数,就是停止没有落在冒泡的路径上。 停止写在组件标签上时,组件内部的节点仍可能把点击送进价格区域。内部节点的父链不保证经过那个修饰符。 在图标外面套一层原生容器,把停止写在容器上。点击从内部出来,先撞上这层,就到不了价格区域。 图标自己的监听只保留改价,不再承担停止。停止和业务调用分成两层,才知道是哪一层没挡住。 参考价格继续读取价格字段。自定义价格只在有值时另外显示。两套金额不要合成一个字段。 有一版示例把参考价格写成了自定义价格的字段。照抄之后,没有自定义价的行会像是金额丢失。修事件时把字段改回去。 包装层只罩住图标,不要罩住参考价格的文字。罩住文字的话,点价格也会被停住,详情就没有入口。 每一行传递自己的商品。改价还要带上所在的外层项。不要写成固定的某一行,否则列表里会改错对象。 图标的名字、颜色、尺寸和左边距保持原样。左边距只是把图标和文字分开,避免一次点到两块。 颜色和尺寸不决定事件往哪走。事件只看监听写在哪一层、用的是点击还是触摸。 两边先统一用点击。停止确认有效之后,再评估要不要改成触摸。只改图标、不改外层,停的是另一条事件。 包装之后若仍然进入详情,说明价格区域外面还有监听。再往外找,不要在组件名上再叠一个停止。 详情函数的参数仍是当前商品。改价函数的参数仍是当前商品和外层项。不要为了修停止而对调这两个函数。 点文字时只应出现详情。点图标时只应出现改价。用这个现象验收,而不是只看修饰符还在不在。 原生容器不要再写成一个同样不转发停止的组件。否则问题会在新的一层上重复。 列表滚动和金额格式化都不是这次双触发的原因。先把停止的范围收成刚好罩住图标。
验收时点一次文字,只进入详情。再点一次图标,只进入改价。参考价仍显示价格字段。包装层罩住图标,不罩住文字。



