!784 refactor(#I2A3BC): tab component replaces div with a on head

* refactor: Tab 组件内部使用 a 标签代替 div
* style: 微调顶部间隙
* refactor: 使用 Tab.Add 新方法精简代码
This commit is contained in:
Argo 2020-12-20 18:54:51 +08:00
parent 909a56b2d0
commit b4f5e69039
7 changed files with 49 additions and 83 deletions

View File

@ -31,11 +31,10 @@
[NotNull]
private Tab? TabSet2 { get; set; }
private async Task AddTab(Tab tabset)
private void AddTab(Tab tabset)
{
var text = $"Tab {tabset.Items.Count() + 1}";
var item = new TabItem();
var parameters = new Dictionary<string, object>
tabset.Add(new Dictionary<string, object>
{
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
@ -46,9 +45,7 @@
builder.AddContent(index++, $"我是新建的 Tab 名称是 {text}");
builder.CloseElement();
})
};
var _ = item.SetParametersAsync(ParameterView.FromDictionary(parameters));
await tabset.Add(item);
});
}
private async Task RemoveTab(Tab tabset)

View File

@ -31,38 +31,29 @@
@code {
private string? RemoveEndableString => (TabSet?.Items.Count() > 4) ? null : "true";
private async Task AddTab()
private void AddTab()
{
if (TabSet != null)
var text = $"Tab {TabSet.Items.Count() + 1}";
tabset.Add(new Dictionary<string, object>
{
var text = $"Tab {TabSet.Items.Count() + 1}";
var item = new TabItem();
var parameters = new Dictionary<string, object>
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
[nameof(TabItem.ChildContent)] = new RenderFragment(builder =>
{
["Text"] = text,
["IsActive"] = true,
["ChildContent"] = new RenderFragment(builder =>
{
var index = 0;
builder.OpenElement(index++, "div");
builder.AddContent(index++, $"我是新建的 Tab 名称是 {text}");
builder.CloseElement();
})
};
item.SetParametersAsync(ParameterView.FromDictionary(parameters));
await TabSet.Add(item);
}
var index = 0;
builder.OpenElement(index++, "div");
builder.AddContent(index++, $"我是新建的 Tab 名称是 {text}");
builder.CloseElement();
})
});
}
private async Task RemoveTab()
{
if (TabSet != null)
if (TabSet.Items.Count() > 4)
{
if (TabSet.Items.Count() > 4)
{
var item = TabSet.Items.Last();
await TabSet.Remove(item);
}
var item = TabSet.Items.Last();
await TabSet.Remove(item);
}
}
}

View File

@ -38,16 +38,10 @@
}
}
private async Task AddTabItem(string text)
private void AddTabItem(string text) => TabSetMenu.Add(new Dictionary<string, object>
{
var item = new TabItem();
var parameters = new Dictionary<string, object>
{
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
[nameof(TabItem.ChildContent)] = text == "计数器" ? DynamicComponent.CreateComponent<Counter>().Render() : DynamicComponent.CreateComponent<FetchData>().Render
};
var _ = item.SetParametersAsync(ParameterView.FromDictionary(parameters));
if (TabSetMenu != null) await TabSetMenu.Add(item);
}
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
[nameof(TabItem.ChildContent)] = text == "计数器" ? DynamicComponent.CreateComponent<Counter>().Render() : DynamicComponent.CreateComponent<FetchData>().Render()
});
}

View File

@ -2,7 +2,7 @@
<h4>整页面级别组件</h4>
<Tips>通过内置组件 <code>Layout</code> 进行整页面布局,可通过 <code>dotnet new bbapp</code> 或者安装 <code>Visual Studio 2019</code> 项目插件选择 <code>Bootstrap Blazor 项目模板</code> 即可自动生成,详细文档请点击 <a href="template" target="_blank">[传送门]</a></Tips>
<Tips class="mt-3">通过内置组件 <code>Layout</code> 进行整页面布局,可通过 <code>dotnet new bbapp</code> 或者安装 <code>Visual Studio 2019</code> 项目插件选择 <code>Bootstrap Blazor 项目模板</code> 即可自动生成,详细文档请点击 <a href="template" target="_blank">[传送门]</a></Tips>
<div class="page-layout-demo-option">
<p>布局调整</p>

View File

@ -48,11 +48,10 @@ namespace BootstrapBlazor.Shared.Pages
}
}
private async Task AddTab(Tab tabset)
private void AddTab(Tab tabset)
{
var text = $"Tab {tabset.Items.Count() + 1}";
var item = new TabItem();
var parameters = new Dictionary<string, object>
tabset.Add(new Dictionary<string, object>
{
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
@ -63,9 +62,7 @@ namespace BootstrapBlazor.Shared.Pages
builder.AddContent(index++, $"我是新建的 Tab 名称是 {text}");
builder.CloseElement();
})
};
var _ = item.SetParametersAsync(ParameterView.FromDictionary(parameters));
await tabset.Add(item);
});
}
private string? RemoveEndableString => (TabSet?.Items.Count() > 4) ? null : "true";
@ -105,22 +102,16 @@ namespace BootstrapBlazor.Shared.Pages
{
var text = item.Text;
var tabItem = TabSetMenu.Items.FirstOrDefault(i => i.Text == text);
if (tabItem == null) await AddTabItem(text ?? "");
if (tabItem == null) AddTabItem(text ?? "");
else await TabSetMenu.ActiveTab(tabItem);
}
private async Task AddTabItem(string text)
private void AddTabItem(string text) => TabSetMenu.Add(new Dictionary<string, object>
{
var item = new TabItem();
var parameters = new Dictionary<string, object>
{
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
[nameof(TabItem.ChildContent)] = text == "计数器" ? DynamicComponent.CreateComponent<Counter>().Render() : DynamicComponent.CreateComponent<FetchData>().Render()
};
var _ = item.SetParametersAsync(ParameterView.FromDictionary(parameters));
await TabSetMenu.Add(item);
}
[nameof(TabItem.Text)] = text,
[nameof(TabItem.IsActive)] = true,
[nameof(TabItem.ChildContent)] = text == "计数器" ? DynamicComponent.CreateComponent<Counter>().Render() : DynamicComponent.CreateComponent<FetchData>().Render()
});
/// <summary>
/// 获得属性方法

View File

@ -31,7 +31,7 @@
}
@foreach (var item in Items)
{
<div role="tab" tabindex="-1" class="@GetClassString(item.IsActive)" @onclick="@(e => OnClickTabItem(item))">
<a href="@item.Url" role="tab" tabindex="-1" class="@GetClassString(item.IsActive)" @onclick:preventDefault="@(!ClickTabToNavigation)" @onclick="@(e => OnClickTabItem(item))">
@if (!string.IsNullOrEmpty(item.Icon))
{
<i class="@GetIconClassString(item.Icon)"></i>
@ -43,7 +43,7 @@
<i class="fa fa-fw fa-close"></i>
</span>
}
</div>
</a>
}
</RenderTemplate>
</div>

View File

@ -199,27 +199,27 @@ namespace BootstrapBlazor.Components
CloseAllTabsText ??= Localizer[nameof(CloseAllTabsText)];
CloseCurrentTabText ??= Localizer[nameof(CloseCurrentTabText)];
await InitRouteTable();
if (ClickTabToNavigation)
{
await InitRouteTable();
}
}
private Task InitRouteTable() => Task.Run(() =>
{
if (ClickTabToNavigation)
var apps = AdditionalAssemblies == null ? new[] { Assembly.GetEntryAssembly()! } : new[] { Assembly.GetEntryAssembly()! }.Concat(AdditionalAssemblies);
var componentTypes = apps.SelectMany(a => a.ExportedTypes.Where(t => typeof(IComponent).IsAssignableFrom(t)));
foreach (var componentType in componentTypes)
{
var apps = AdditionalAssemblies == null ? new[] { Assembly.GetEntryAssembly()! } : new[] { Assembly.GetEntryAssembly()! }.Concat(AdditionalAssemblies);
var componentTypes = apps.SelectMany(a => a.ExportedTypes.Where(t => typeof(IComponent).IsAssignableFrom(t)));
foreach (var componentType in componentTypes)
var routeAttributes = componentType.GetCustomAttributes<RouteAttribute>(false);
foreach (var template in routeAttributes.Select(t => t.Template))
{
var routeAttributes = componentType.GetCustomAttributes<RouteAttribute>(false);
foreach (var template in routeAttributes.Select(t => t.Template))
{
RouteTable.TryAdd(template.Trim('/'), componentType);
}
RouteTable.TryAdd(template.Trim('/'), componentType);
}
Navigator.LocationChanged += Navigator_LocationChanged;
InvokeAsync(() => AddTabByUrl(Navigator.ToBaseRelativePath(Navigator.Uri)));
}
Navigator.LocationChanged += Navigator_LocationChanged;
InvokeAsync(() => AddTabByUrl(Navigator.ToBaseRelativePath(Navigator.Uri)));
});
private void Navigator_LocationChanged(object? sender, LocationChangedEventArgs e)
@ -280,14 +280,7 @@ namespace BootstrapBlazor.Components
{
Items.ToList().ForEach(i => i.SetActive(false));
if (OnClickTab != null) await OnClickTab(item);
if (ClickTabToNavigation)
{
Navigator.NavigateTo(item.Url ?? "");
}
else
{
item.SetActive(true);
}
if (!ClickTabToNavigation) item.SetActive(true);
}
/// <summary>