-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Building small, reusable components and composing them into larger components is a great way to build a web application that is used by many client side JavaScript frameworks today. It would be great for this to be brought to Razor/Blazor but to also blur the lines between the client and server too.
Following on from this thread talking about static file handling. Perhaps the Vue.js concept of single file components could be taken to the extreme, so Blazor could handle a HTML template, server side Razor, client side Blazor and CSS all in one file (or separated if you'd like but in my experience if you make your components small and reusable, a single file really works well) with the C# being shared and runnable on the client and server side. I envisage something like this:
ExampleComponent.cshtml
@Model Customer
<template>
<p>HTML which can be rendered on the client using Blazor or the Server using Razor.</p>
<p>@Customer.Name</p>
</template>
<style>
p {
font-size: 20px;
}
</style>
<script>
public class Customer
{
public string Name { get; set; }
}
this.Model = new Customer() { Name = "Server Rendered" }
this.window.OnLoad += (sender, e) =>
{
this.Model.Name = "Client Rendered";
};
</script>
The HTML would be prerendered on the server and show the customer name as 'Server Rendered'. When the event handler fires, the model text is changed to 'Client Rendered'.
There would need to be some sort of build system to extract CSS into a separate file, compile the C# code for the server using Razor but also for the client into web assembly format using Blazor. Finally the HTML template would also need to be compiled to C# as it is today for Razor but also for Blazor.
Making use of such a component could just use the web component standards, so it might look something like this:
ComponentImports.cshtml
@addComponents "ExampleComponent, MyAssemblyName"
@addComponents "*, MyOtherAssemblyName"
ExampleComponentUsage.cshtml
<template>
<h1>Using the component below</h1>
<example-component />
</template>