Closed wdpm closed 1 year ago
很高心能以这样的方式相遇ヾ(•ω•`)o
说起来你可能不信,目前主站也是 前后端分离
的哦~
很奇怪吧,.Net 的 Blazor 框架我第一眼看到也以为是前后端不分离。
但其实,我们现在有两个前端呢,一个是在用户本地运行的 WASM
客户端,一个是通过建立 WebSocket
实时同步渲染页面的 SSR
服务端。
这两个客户端都访问同一套后端API接口获取数据,所以应该算是 前后端分离
吧o((>ω< ))o
小声说一句:这两个前端是共享代码的,不用担心我们写两遍代码哦~
那么,我就私自把标题的疑问改成“【Blazor】->【Vue 3】的动机”咯?
目前主站的代码确实十分混杂,不过都是因为我菜鸡的编程水平,可不是因为 Blazor
框架不行哦。
因为没有美工,几乎所有UI界面都是我自己设计的。对了,现在的前端页面是重构过三次的结果,也只是到了还能看下去的地步。这三次重构下来确实有很多历史遗留问题,但也没到难以维护的地步。
更加丰富的交互行为在 Blazor
框架下面也可以轻松实现,但还是因为我是个菜鸡,没有熟练掌握 Html/CSS
,做不出什么炫酷的特效。
回到正题,为什么开始使用 Vue 3
重构前端?
Vue 3
重构前端Blazor
的 SSR
模式消耗大量服务器资源,WASM
模式消耗大量网络流量Blazor
的 SSR
模式由于使用 WebSocket
建立实时链接,网络延迟将会造成一些难以解决的bugBlazor
开发是因为我只会这一种技术,但是考虑到 Blazor
以及 .Net
未来难以在中国推广流行,也就意味着难以找到继续维护主站代码的人员,不利于资料站的维系。于是需要使用 Vue、React 等流行前端技术重构
其实后端也是这样,ASP .NET Core 应尽早换成 Spring 等流行后端框架。
综上所述,开始使用 Vue 3
重构前端。
我们会继续加油的,欢迎加入我们一起添砖加瓦呀ヾ(^▽^*)))
我之前的言论有误,是我太武断了,抱歉。我决定去调查一下blazor,因为此前我没用过这个东西,.Net生态不熟悉。
我注意到了这个文章: Blazor 应用托管模型
Blazor 应用可以通过以下方式托管:
BlazorWebAssembly 应用使用基于 WebAssembly 的 .NET 运行时在浏览器中直接执行。BlazorWebAssembly 应用的工作方式类似于 Angular 和 React 等前端 JavaScript 框架。 但不是编写 JavaScript,而是编写 C#。 .NET 运行时与应用、应用程序集和任何必需的依赖项一起下载。 无需浏览器插件和扩展。
=> WSAM 客户端
在 Blazor Server 应用中,组件在服务器上运行,而不是在浏览器中的客户端运行。浏览器中发生的 UI 事件通过实时连接发送到服务器。 事件被分派到正确的组件实例。 组件将呈现,计算的 UI 差异被序列化后发送到浏览器并在其中应用于 DOM。
=> 实时连接 websocket
counter示例代码。Blazor 。
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
这个样例在于控制 @currentCount 值的生成。过于简单,于是我再次查看CnGal的源代码,下面取一个复杂视图的渲染作为例子:
<li class="@("nav-item "+Model.ClassNames)" style=" display: flex; justify-content: center;" role="presentation">
<a class="@("text-center rounded tab-"+Model.Type.ToString()+"-color"+(IsSelected?" active ":""))"
style="cursor:pointer;width:100%"
id="@("pills"+Model.RandomIndex+"-"+Model.Index.ToString()+"-tab")"
data-bs-toggle="pill"
href="@("#pills"+Model.RandomIndex+"-"+Model.Index.ToString())"
role="tab"
aria-controls="@("pills"+Model.RandomIndex+"-"+Model.Index.ToString())"
aria-selected="@(IsSelected.ToString())"
@onclick="@(()=>Model.OnTabClick.InvokeAsync(Model.Index))">
@if (Model.Type == TableItemType.Bottom)
{
<i class="@("fa fa-fw fa-lg li-user-space-small-icon "+Model.Icon)"></i>
<div class="li-user-space-small-text">@Model.Text</div>
}
else if (Model.Type == TableItemType.Pivot)
{
<div class="li-user-space-small-text">@Model.Text</div>
<div class="line w-100 mt-2" style="height:2px"></div>
}
else
{
<div class="line ps-2 pe-2">@Model.Text</div>
}
</a>
</li>
@code {
[Parameter]
public TabViewItemModel Model { get; set; }
private bool IsSelected => Model.Index == Model.DefaultIndex;
}
这个例子非常典型:
style=" display: flex; justify-content: center;"
"@("text-center rounded tab-"+Model.Type.ToString()+"-color"+(IsSelected?" active ":""))"
<div class="line ps-2 pe-2">@Model.Text</div>
@Model.Text 指的是数据的渲染位置以及name。这些机制和现在的主流前端框架Vue/React/Angular很像,但是API的混杂编写问题依旧得不到改善。就和时代的眼泪ASP,JSP,PHP一样。
微软即使下了一番苦功,即使使用WebAssembly先进的技术,也设计不好简洁的API。这个锅,需要后端渲染来背,谁来都洗不动。
<a class="@("text-center rounded tab-"+Model.Type.ToString()+"-color"+(IsSelected?" active ":""))"
style="cursor:pointer;width:100%"
id="@("pills"+Model.RandomIndex+"-"+Model.Index.ToString()+"-tab")"
data-bs-toggle="pill"
href="@("#pills"+Model.RandomIndex+"-"+Model.Index.ToString())"
role="tab"
aria-controls="@("pills"+Model.RandomIndex+"-"+Model.Index.ToString())"
aria-selected="@(IsSelected.ToString())"
@onclick="@(()=>Model.OnTabClick.InvokeAsync(Model.Index))">
@if (Model.Type == TableItemType.Bottom)
这种代码维护难度很高,因为代码的可读性差。如果换成前端MVVM框架,情况应该会得到改善。
这也是为何我之前就提出的问题:
更加丰富的交互行为在 Blazor 框架下面也可以轻松实现,但还是因为我没有熟练掌握 Html/CSS ,做不出什么炫酷的特效。
可以实现和[轻松实现/适合用来实现]是不同的,为不同的需求和context,选择最为合适的技术栈,个人认为才是最好的选择。
另外,的确C# .Net 略显苍老,Java/Pyton/Go/Rust/Node 都有非常丰富的Web生态。
另外,早日解耦前后端,和拥抱新的主流技术,可以减少以后的技术债。
开源项目的创建不难,维护才是最难的。
我们会继续加油的,欢迎加入我们一起添砖加瓦呀ヾ(^▽^*)))
不了,暂时没这个打算,我自己的坑太多了,填不过来。我会偶尔关注你们这个CnGal的项目进展的。
非常高兴有人愿意了解 Blazor
具体实现原理,但是好像后文中我写的代码让你产生了一些误会,非常抱歉 ≧ ﹏ ≦
这些误会基本上都是由我水平很低的代码引起的,再次向你道歉 <(_ _)>
这个样例在于控制 @currentCount 值的生成。过于简单,于是我再次查看CnGal的源代码,下面取一个复杂视图的渲染作为例子: https://github.com/CnGal/CnGalWebSite/blob/master/CnGalWebSite/CnGalWebSite.Shared/AppComponent/Normal/Tabs/TabViewItem.razor
就像前文中提到的那样,我们的前端页面布局重构过三次,作为开发者的我并不熟悉 Html/CSS
,没有遵守MVVM模式的开发规范,才写出了这样一个贻笑大方的组件。
CnGalWebSite.Shared/AppComponent/
目录下是第一次适配移动端并尝试自己写的组件,如你所见十分丑陋。因此我也吸
取了教训:尽量使用组件库,优化代码书写方式。这个目录下面的组件也几乎不再使用了。
CnGalWebSite.Shared/MasaComponent/
目录下是在此基础上重构的组件,应该会更好一点。
例如下面这段代码作为例子可能比较好: https://github.com/CnGal/CnGalWebSite/blob/master/CnGalWebSite/CnGalWebSite.Shared/MasaComponent/Shared/Editors/Entries/AudioCard.razor
这些机制和现在的主流前端框架Vue/React/Angular很像,但是API的混杂编写问题依旧得不到改善。就和时代的眼泪ASP,JSP,PHP一样。
非常抱歉我写的代码让你觉得是 Blazor
会产生 API的混杂编写问题
,实际上这是人的问题而不是框架的问题。
微软即使下了一番苦功,即使使用WebAssembly先进的技术,也设计不好简洁的API。这个锅,需要后端渲染来背,谁来都洗不动。
这个锅不应该由微软来背,是我写出这样代码的责任。
Blazor
的设计十分优秀, Blazor
是标准的现代前端框架,Blazor
可以应用MVVM模式,
Blazor
有很多优秀的开源项目,比如我们使用的组件库 :
Masa Blazor,开源项目地址:https://github.com/BlazorComponent/MASA.Blazor
Bootstrap Blazor,开源项目地址:https://gitee.com/LongbowEnterprise/BootstrapBlazor
如果方便的话可以阅读一下他们的源码,也许你会有一些不一样的感受。
总之,非常抱歉造成了这样的误会 >︿<
我认为我没有误会你的意思,反而可能你有点误解我的意思了。
我重新梳理了一下我的疑问关键点,我指的API的混杂编写问题是指:
后端和前端逻辑都在在一个文件来写,指的是代码的编写/维护问题。不管它最后怎么渲染,是客户端还是服务端,还是各种hydrate,代码可读性此时是弱于前端和后端完全分离出不同的项目/模块来编写的。
目前这个 CnGalWebSite.VueTrial 看起来就很现代化,渲染关键逻辑都在前端,使用标准JS框架/库来解决就很直接。仅仅需要后端的API,使用AJAX请求来获取数据,然后局部刷新就好。
而 blazor 这类框架企图使用其他语言(这里是C#),对前端视图层的逻辑进行一层抽象,然后利用WSAM编译到浏览器中执行。加一层抽象就加一层复杂度,毕竟浏览器不能直接执行C#,只能直接执行JS。可能他们的出发点是考虑让这个blazor框架能直接接管网站开发的后端逻辑和UI界面,而不再需要另外的独立前端模块。优点和缺点都很明显。
个人觉得稍微复杂一点的网站项目,前后端代码分离还是非常合理的选择。后端只管REST API,返回数据。前端主要管界面渲染,使用AJAX请求和后端API交互。
顺便说一句,blazor来做MVVM,对比成熟火热的Vue/React框架而言,几乎没有优势。
容易维护的代码项目才有未来,不能维护和难以读懂的代码项目,一般会走向衰亡。
这个issue没有进一步讨论的意义了,当初我只是路过问一下。
本质上就是:分离出前端模块/后端模块,让代码更容易维护和可读,保持常绿。
嗯嗯,非常感谢,那我就先关闭这个issue了
路过。偶然间发现这样一个关于GAL的百科生态建设网站,类似于VNDB。 目前主站的源码扫了下,是后端template渲染,顺藤摸瓜,见到这个使用Vue 3进行前端解耦的孵化项目。
我想问下前端分离的动机?
无利益的ACGN开源生态项目,加油。