在我的Blazor组件中,我经常根据条件语句来渲染组件,例如
@if (_contact.IsCustomer)
{
<SalesOrdersList Customer="@_contact" />
}
或者从循环中获取,例如
@foreach(var salesOrder in _customer.SalesOrders)
{
<SalesOrderSummary SalesOrder="@salesOrder" />
}
当我更改状态时,我想为状态转换设置动画,以便组件淡入/淡出。在上面的示例中,当IsCustomer
发生更改时,或者在SalesOrders
集合中添加或删除记录时,可能会发生这种情况。
我可以看到添加组件时如何通过具有CSS类的组件实现该效果,该CSS类具有在组件渲染时发生的动画淡入-例如如Chris Sainty's excellent toast example
所示我想不出在删除组件时会怎么做,因为当该部分DOM重新呈现时,该组件会停止存在?
React拥有react-transition-group来处理过渡期,但是到目前为止,我在Blazor中找不到类似的东西吗?
有什么方法可以添加动画以删除Blazor中的组件吗?
另一个经常被动画化的状态转换是改变“页面”。再说一次,我现在找不到在Blazor中做到这一点的方法吗?实际上,这只是删除旧页面组件和添加新页面组件的动画,但是在某些框架中,这是在路由级别而不是组件级别完成的-目前我在Blazor的任何一个级别都找不到任何东西?
答案 0 :(得分:3)
Blazor没有涵盖这种情况,为此,您将需要使用CSS。很难给出一个具体的示例,因为它取决于您希望动画的工作方式以及哪种样式,但是我建议您检查一下CSS过渡和关键帧。
这里有一些很好的资源
正如您在问题处理中提到的那样,我目前还无法确定要删除的项目。因此,不幸的是,我无济于事。
答案 1 :(得分:3)
我们可以使用 CSS 显示/隐藏。只需确保处理null
参数,这些参数在隐藏时会传递给组件。
假设我们有Person
组件,如下所示:
<style>
.container{
display:inline-block;
width:@width;
height:@height;
color:white;
background-color:blue;
}
.fade-out{
animation: fade @AnimTime linear forwards;
}
.spin-in{
animation: spin @AnimTime linear forwards;
}
@@keyframes fade {
0% {opacity:1;}
99% {width:@width; height:@height;}
100% {width:0px;height:0px; opacity:0;}
}
@@keyframes spin {
0% {width:0px;height:0px; transform: rotate(0deg);}
99% {width:@width; height:@height;}
100% {width:@width;height:@height;transform: rotate(1440deg);}
}
</style>
<div class="container @(IsShown?"spin-in":"fade-out")">
<span>@(Name??"")</span>
</div>
@code {
string width="100px";
string height="20px";
[Parameter]
public string Name { get; set; }
[Parameter]
public string AnimTime { get; set; }
[Parameter]
public bool IsShown {get; set;}
}
,我们在另一个页面/组件中使用它,如下所示:
<button @onclick="(_=>{isShown=!isShown;})">Switch</button>
<span>Left hand of component</span>
<Person Name="Jack" AnimTime="2s" IsShown=@isShown/>
<span>Right hand of component</span>
@code{
bool isShown=true;
}
我在 CSS 中使用了@width
,@height
,@AnimTime
变量来表明可能性是无限的。
我应该注意,Blazor组件中的keyframes
应该以符号(@@
)的两倍开头。
在BlazorFiddle上观看实时演示,仅在JSFiddle上观看html + CSS。
如果用户单击 close 或 X 之类的按钮,则可以在鼠标向下滑动期间挤压0.1s或0.2s的短动画-向上。按下鼠标会触发动画,但是按下鼠标会删除组件。我在here
之前进行了编码答案 2 :(得分:0)
对于组件移除方面:
根据Chris Sainty的回答,目前似乎没有任何方法可以解决或处理从渲染树/ DOM中删除组件的问题。
我在AspNetCore存储库中为此添加了一个GitHub feature request,如果发生这种情况,我将对其进行更新。
答案 3 :(得分:0)
我决定采用以下方法在元素被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);
}
}
,它在父页面或组件中的用法如下:
@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;
}
}
和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;
}
}
答案 4 :(得分:0)
关于这个问题的页面过渡动画部分......
blazor 中的转换并不是一蹴而就的。您必须考虑重置状态和保留状态模式,例如在移回之前的路线并需要保留滚动位置时需要这样做。使用 css 的过渡动画是实现此目的的好方法。有一种解决方案允许使用您选择的任何转换方法(此处的答案中的其他地方提供了示例)。
我建议您查看这个 nuget 包和 github 存储库,它们存在以解决这个确切的问题。