如何为Blazor中的状态转换设置动画?

tom*_*dox 5 c# blazor

在我的Blazor组件中,我经常根据条件语句来渲染组件,例如

@if (_contact.IsCustomer)
{
    <SalesOrdersList Customer="@_contact" />
}
Run Code Online (Sandbox Code Playgroud)

或从循环开始,例如

@foreach(var salesOrder in _customer.SalesOrders)
{
    <SalesOrderSummary SalesOrder="@salesOrder" />
}
Run Code Online (Sandbox Code Playgroud)

当我更改状态时,我想为状态转换设置动画,以便组件淡入/淡出。在上面的示例中,当IsCustomer更改或从SalesOrders集合中添加或删除记录时,可能会发生这种情况。

动画添加组件

我可以看到添加组件时如何实现的,该组件具有CSS类,该类具有在组件渲染时会发生的动画淡入效果,例如Chris Sainty出色的Toast示例中所示

动画移除组件

我不认为删除组件时会怎么做,因为当该部分DOM重新呈现时,该组件会停止存在吗?

React具有处理过渡期的react-transition-group,但是到目前为止,我在Blazor中找不到类似的东西吗?

有什么方法可以添加动画以删除Blazor中的组件吗?

动画页面过渡

另一个经常被动画化的状态转换是改变“页面”。再说一次,我现在找不到在Blazor中做到这一点的方法吗?实际上,这只是删除旧页面组件和添加新组件的动画,但是在某些框架中,这是在路由级别而不是组件级别完成的-目前我在Blazor的任何一个级别都找不到任何东西?

Chr*_*nty 8

Blazor 不涵盖这种情况,为此,您需要使用 CSS。很难给你一个具体的例子,因为它取决于你希望你的动画如何工作以及使用什么样的风格,但我建议检查 CSS 过渡和关键帧。

这里有一些很好的资源

正如你在你的问题中提到的,处理被删除的项目是我还无法弄清楚的事情。所以不幸的是,我无能为力。

  • 谢谢克里斯,很高兴不仅仅是我!我有时需要给你买瓶啤酒,你的评论和博客确实帮助我提高了 Blazor 的学习曲线! (2认同)

tom*_*dox 5

对于组件移除方面的事情:

我在 AspNetCore 存储库中添加了一个用于删除的GitHub 功能请求。Microsoft 的 Steve Sanderson 概述了使用 Blazor 框架公开的 API 应该已经可以删除动画组件,但它可能会受益于编写一个包以使其更易于实现的人:

我期望的解决方案是创建一个渲染列表或单个项目的动画组件,并结合逻辑来延迟每个项目的删除,以便可以将其动画化。Blazor 已经为模板组件提供了很好的原语,因此生成的 API 应该非常好。这与其他 SPA 框架中使用的解决方案本质上是相同的。

这可以在用户代码中实现,并且不需要内置框架功能。我并不是说这很容易,但希望社区中的某个人会抽出时间去做。这是我可能在某个时候自己做但在短期内有其他优先事项的事情。

dazinator / @Darrell 已经接受了这一点,并制作了Blazor Deferred Remove Nuget 包来做到这一点。我还没有尝试过,但看起来实现这一目标需要什么。

现在还有Blazor.Animate 包


Dar*_*ell 5

更新:我没有使用下面的内容,而是在 GitHub 上为此提供了一个改进的解决方案(不依赖于 Task.Delay):https : //github.com/dazinator/BlazorDeferredRemove

在 blazor 从 DOM 中删除元素之前,我决定采用以下方法来处理淡出元素。这是一种使用 Task.Delay 的解决方法,折衷是因为我使用 Task.Delay 并指定时间(以毫秒为单位)这次需要与您在 css 中用于过渡的持续时间保持一致 - 否则元素可能会被 blazor 删除在转换完成之前(或之后):

可重用的 Transition.razor 组件:

    <div class="@(ToggleActive ? ToggleTransitionOnCssClassName: ToggleTransitionOffCssClassName)">
        @ChildContent;
    </div>

    @code {

    [Parameter] RenderFragment ChildContent { get; set; }

    [Parameter] string ToggleTransitionOnCssClassName { get; set; } = "";
    [Parameter] string ToggleTransitionOffCssClassName { get; set; } = "";

    [Parameter] int TransitionDurationMilliseconds { get; set; } = 200;

    public bool ToggleActive { get; set; }

    [Parameter] EventCallback<bool> TransitionEnded { get; set; }

    public async Task ToggleTransition()
    {
        ToggleActive = !ToggleActive;
        await Task.Delay(TransitionDurationMilliseconds);
        await TransitionEnded.InvokeAsync(ToggleActive);
    }


    }
Run Code Online (Sandbox Code Playgroud)

它在父页面或组件中像这样使用:

         @if (RenderThingy)
        {
            <Transition @ref="Transition" TransitionDurationMilliseconds="500" ToggleTransitionOnCssClassName="m-fadeOut" ToggleTransitionOffCssClassName="m-fadeIn" TransitionEnded="@TransitionComplete">
                <RenderThingy OnDismissed="@OnDismissed"></RenderThingy>
            </Transition>
        }

@code {

    Transition Transition { get; set; }
    bool RenderThingy {get; set;} = true;

    async Task OnDismissed()
    {
        await Transition.ToggleTransition();
    }
    private void TransitionComplete(bool toggleState)
    {
        RenderThingy = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

和CSS:

.m-fadeIn {
    visibility: visible;
    opacity: 1;
    animation: fadein 500ms;
}

@keyframes fadein {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.m-fadeOut {
    animation: fadeout 500ms;
}

@keyframes fadeout {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;       
    }
}
Run Code Online (Sandbox Code Playgroud)