Spring ViewComponent allows you to create typesafe, reusable & encapsulated server-rendered UI components.
ViewComponents consolidate the logic needed for a template into a single class, resulting in a cohesive object that is easy to understand. (Source: ViewComponent for Rails)
A Spring ViewComponent is a Spring Bean that defines the context for our Template:
We define the context by creating a record that implements the ViewContext interface
Next, we add the @ViewComponent
annotation to a class and define a method that returns the SimpleView
record.
A ViewComponent always needs a corresponding HTML Template. We define the Template in the SimpleViewComponent.[html/jte/kte] In the same package as our ViewComponent class.
We can use Thymeleaf
// SimpleViewComponent.html
<!--/*@thymesVar id="d" type="de.tschuehly.example.thymeleafjava.web.simple.SimpleViewComponent.SimpleView"*/-->
<div th:text="${simpleView.helloWorld()}"></div>
or JTE
// SimpleViewComponent.jte
@param de.tschuehly.example.jte.web.simple.SimpleViewComponent.SimpleView simpleView
<div>${simpleView.helloWorld()}</div>
or KTE
@param simpleView: de.tschuehly.kteviewcomponentexample.web.simple.SimpleViewComponent.SimpleView
<div>
<h2>This is the SimpleViewComponent</h2>
<div>${simpleView.helloWorld}</div>
</div>
We can then call the render method in our controller to render the template.
If you want to get started right away you can find examples for all possible language combinations here: Examples
We can nest components by passing a ViewContext as property of our record, if we also have it as parameter of our render method we can easily create layouts:
In Thymeleaf we render the passed ViewComponent with the view:component="${viewContext}"
attribute.
<nav>
This is a navbar
</nav>
<!--/*@thymesVar id="layoutView" type="de.tschuehly.example.thymeleafjava.web.layout.LayoutViewComponent.LayoutView"*/-->
<div view:component="${layoutView.nestedViewComponent()}"></div>
<footer>
This is a footer
</footer>
In JTE/KTE we can just call the LayoutView record directly in an expression:
@param layoutView: de.tschuehly.kteviewcomponentexample.web.layout.LayoutViewComponent.LayoutView
<nav>
This is a Navbar
</nav>
<body>
${layoutView.nestedViewComponent}
</body>
<footer>
This is a footer
</footer>
You can enable hot-reloading of the templates in development, you need to have Spring Boot DevTools as a dependency.
spring.view-component.local-development=true
LATEST_VERSION on Maven Central
LATEST_VERSION on Maven Central
LATEST_VERSION on Maven Central
Spring ViewComponent wraps the Spring MVC container using an AspectJ Aspect and automatically resolves the template and puts the ViewContext in the ModelAndViewContainer