You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中如何通过点击事件停止子组件内的滚动ticker动画?

搞定Vue组件的滚动动画停止问题~

你的需求很明确:点击新闻项后,要停止横向滚动的ticker动画,同时把它改成和普通菜单一样的样式。因为Vue的单向数据流规则,子组件不能直接修改prop,所以咱们得从父组件控制状态这个方向入手——刚好你已经在父组件里用readNewsList跟踪已读状态了,完全可以利用这个来实现需求。

第一步:让父组件动态控制itemType

你现在给所有新闻项都固定传了itemType="news",咱们改成根据已读状态动态传值:如果新闻已经被读过,就传空字符串,否则传"news"。这样子组件会自动切换显示普通文本,动画自然就停了。

修改MainMenu.vue里的组件调用:

<MainMenuItem 
  v-for="news in newsList" 
  :key="news.id" 
  @click="openNews(news)" 
  :title="news.title" 
  :itemType="readNewsList[news.id] ? '' : 'news'" <!-- 改成动态绑定 -->
  :class="{ readLink: readNewsList[news.id] }" 
  menuIcon="contactless" 
/>

这样一来,用户点击新闻后,readNewsList更新,子组件的itemType自动变成空,原来的ticker容器会被隐藏,换成普通文本容器,动画直接停止,同时readLink类也会生效,字体权重改成500,完美契合你的需求。

第二步:可选的精细动画控制(如果不想切换容器)

要是你不想切换容器,只想暂停动画而保留布局,那可以在子组件里通过动态类来控制动画状态。

先给子组件加个isRead的prop

在父组件里传递已读状态:

<MainMenuItem 
  ...
  :isRead="readNewsList[news.id]"
/>

子组件接收这个prop:

props: {
  // 其他props不变...
  isRead: {
    type: Boolean,
    default: false
  }
}

然后修改子组件的样式和模板

给ticker-item加个暂停动画的类:

._ticker-item
  display: inline-block
  padding-left: 100%
  animation: ticker 8s linear infinite
  &.ticker-paused
    animation-play-state: paused

模板里绑定这个类:

<div v-if="itemType === 'news'" class="_ticker">
  <div class="ellipsis _ticker-item" :class="{ 'ticker-paused': isRead }">{{ title }}</div>
</div>

这样已读之后,动画会暂停,同时readLink类也会修改字体权重,效果也能达到。

为啥不推荐子组件自己存状态?

虽然你可以在子组件里定义data来跟踪是否被点击,但这样状态就分散了——你已经在父组件的readNewsList里管理已读状态了,统一在父组件控制更符合Vue的单向数据流原则,后续维护起来也更方便,不会出现状态不一致的问题。

最后验证效果

点击新闻后,openNews会更新seenNewsPosts,readNewsList跟着变化,然后:

  1. 子组件的itemType变成空(或者动画被暂停)
  2. readLink类自动加上,字体权重降低
  3. 滚动动画停止,和普通菜单样式一致

内容的提问来源于stack exchange,提问作者LovelyAndy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:23:14