在Blazor中有没有相当于Vue的 nextTick() 的方法?以及在像对条件渲染组件进行向下滑动动画这样的场景中,该如何处理?

前端开发 2026-07-08

下面这段向下滑动的动画在 ul 元素预挂载时能正常工作(虽然并非完全顺滑,但过渡效果还是可见的):

<ul @ref=@validationErrorsMessagesList>

  @foreach (string validationErrorMessage in validationErrorsMessagesCopyForAnimating)
  {
    <li @key=@validationErrorMessage>
      @(validationErrorMessage)
    </li>
  }

</ul>

在此处输入图片描述

下滑动画是通过 JavaScript互操作 调用的。

protected void animateErrorsMessagesListIfMust()
{
  if (this.validationErrorsMessages.Any())
  {
    this.validationErrorsMessagesCopyForAnimating = this.validationErrorsMessages.ToArray();

    //- `javaScriptFunctionality.ExpandingAnimation.Animate` uses JavaScript interop internally
    _ = this.javaScriptFunctionality.ExpandingAnimation.Animate(
      new JavaScriptFunctionality._ExpandingAnimation.CompoundParameter
      {
        duration__seconds = this.errorsListAnimationDuration__seconds,
        targetElement = this.validationErrorsMessagesList
      }
    ); 
  }
}

然而,将该元素保持为预挂载状态可能并非总是可取的(例如,样式被破坏的情况)。这意味着在像 ul 这样的元素被条件渲染时,应该有一个解决方案:

@if (mustDisplayErrorsMessagesIfAny && validationErrorsMessagesCopyForAnimating.Any())
{
  <ul @ref=@validationErrorsMessagesList>

    @foreach (string validationErrorMessage in validationErrorsMessagesCopyForAnimating)
    {
      <li @key=@validationErrorMessage>
        @(validationErrorMessage)
      </li>
    }

  </ul>
}

目前,这种做法将导致过渡被打断:

在此处输入图片描述

原因已知:过渡是在尚未挂载的元素上启动。

但解决办法呢?在Vue中,对于这种情况有一个 nextTick() 函数。Blazor呢?还不确定这个问题是否只能通过生命周期钩子来解决。

解决方案

OnAfterRenderAsync 中触发动画;这相当于Blazor中的 nextTick()

所以,大致可以这样:

private bool _animateErrors;

protected void animateErrorsMessagesListIfMust()
{
    if (this.validationErrorsMessages.Any())
    {
        this.validationErrorsMessagesCopyForAnimating =
            this.validationErrorsMessages.ToArray();

        _animateErrors = true; // ensure we only run once per trigger

        StateHasChanged(); // force render
    }
}

然后

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (_animateErrors && validationErrorsMessagesList.Id != null)
    {
        _animateErrors = false;

        await this.javaScriptFunctionality.ExpandingAnimation.Animate(
            new JavaScriptFunctionality._ExpandingAnimation.CompoundParameter
            {
                duration__seconds = this.errorsListAnimationDuration__seconds,
                targetElement = this.validationErrorsMessagesList
            }
        );
    }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章