父组件:
<p>@X</p>
<TestComponent @bind-x="@X"></TestComponent>
@code {
private int _X;
public int X
{
get=>_X;
set
{
_X = value;
StateHasChanged();
}
}
}
子组件:
<p>@x</p>
<button @onclick="Add">Add</button>
@code {
[Parameter]
public int x { get;set; }
[Parameter]
public Action<int>? xChanged { get; set; }
private void Add()
{
x++;
xChanged?.Invoke(x);
}
}
包含几个步骤:
- 在父组件引入子组件时使用@bind-,表明不是单向而是双向绑定;
- 子组件中,需要引入一个委托(一般Action就够用),委托名称就是子组件参数属性名+Changed,T就是绑定参数的类型,参数就是这个绑定的参数。这个委托用Invoke触发以后,x的值就传回了X;
- 由于内部组件之间参数的传递并不会触发UI渲染,父组件需要重写X的属性,以便在其值改变的时候触发StateHasChanged()。
- EventCallBack<>就是用来替换Action<>委托的,其好处就是可以自动触发StateHasChanged(),而不用再去手写属性了。
父组件:
<p>@X</p>
<TestComponent @bind-x="@X"></TestComponent>
@code {
public int X{ get; set;}
}
子组件:
<p>@x</p>
<button @onclick="Add">Add</button>
@code {
private int _x;
[Parameter]
public int x { get;set; }
[Parameter]
public EventCallBack<int>? xChanged { get; set; }
private void Add()
{
x++;
xChanged?.InvokeAsync(x);
}
}
- 引用类型的参数传递有一点点特殊,其实父组件传递给子组件时只是复制了引用,子组件中改变参数,父组件中同样也会被修改,它们之间天然是同步的,只不过父组件在没有重新渲染前是看不到的。如果有一个Person类型的对象person,这样写父组件:
<p>@person.Name</p>
<TestComponent person="@person" personChanged="Fresh"></TestComponent>
@code {
public Person person { get; set; } = new Person { Name = "John Doe" };
private void Fresh()
{
StateHasChanged();
}
子组件:
<p>@person.Name</p>
<button @onclick="AddString">AddChar</button>
@code {
[Parameter]
public Person person { get; set; }
[Parameter]
public EventCallback<Person> personChanged { get; set; }
private void AddString()
{
person.Name += "a";
personChanged.InvokeAsync();
}
}
你会发现在父组件中既没有用@bind-双向绑定,子组件中也没有通过EventCallback回传参数,只是给这个personChanged回调委托添加了一个处理StateHasChanged()函数,在点击按钮后,父子组件同时发生了变化。如果进行了双向绑定,则必须回传参数,反之也一样。
值得一提的是,如果要给EventCallback委托添加函数,那么不可将其设为可空类型。
861

被折叠的 条评论
为什么被折叠?



