1. Обзор
В этом руководстве мы рассмотрим пример приложения, которое отображает одну страницу с помощью внешнего интерфейса Vue.js, используя Spring Boot в качестве внутреннего интерфейса.
Мы также будем использовать Thymeleaf для передачи информации в шаблон.
2. Настройка весенней загрузки
Приложение pom.xml
использует зависимость spring-boot-starter-thymeleaf
для отрисовки шаблона вместе с обычным spring-boot-starter-web
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.0</version>
</dependency>
Thymeleaf по умолчанию ищет шаблоны представлений в templates/
, мы добавим пустой index.html
в src/main/resources/templates/index.html
. Мы обновим его содержимое в следующем разделе.
Наконец, наш контроллер Spring Boot будет находиться в src/main/java
:
@Controller
public class MainController {
@GetMapping("/")
public String index(Model model) {
model.addAttribute("eventName", "FIFA 2018");
return "index";
}
}
Этот контроллер отображает один шаблон с данными, переданными в представление через объект веб-модели Spring с использованием model.addAttribute
.
Запустим приложение, используя:
mvn spring-boot:run
Перейдите по адресу http://localhost:8080
, чтобы увидеть индексную страницу. В этот момент он, конечно, будет пуст.
Наша цель — заставить страницу распечатать что-то вроде этого:
Name of Event: FIFA 2018
Lionel Messi
Argentina's superstar
Christiano Ronaldo
Portugal top-ranked player
3. Рендеринг данных с помощью компонента Vue.Js
3.1. Базовая настройка шаблона
В шаблоне давайте загрузим Vue.js и Bootstrap (необязательно) для визуализации пользовательского интерфейса:
// in head tag
<!-- Include Bootstrap -->
// other markup
// at end of body tag
<script
src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js">
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js">
</script>
Здесь мы загружаем Vue.js из CDN, но вы также можете разместить его, если это предпочтительнее.
Мы загружаем Babel в браузере, чтобы написать на странице код, совместимый с ES6, без выполнения шагов транспиляции.
В реальном приложении вы, скорее всего, будете использовать процесс сборки с помощью таких инструментов, как транспайлер Webpack и Babel, вместо использования Babel в браузере.
Теперь сохраним страницу и перезапустим с помощью команды mvn spring-boot
: run
. Обновляем браузер, чтобы увидеть наши обновления; пока ничего интересного.
Далее давайте создадим пустой элемент div, к которому мы прикрепим наш пользовательский интерфейс:
<div id="contents"></div>
Далее мы настраиваем приложение Vue на странице:
<script type="text/babel">
var app = new Vue({
el: '#contents'
});
</script>
Что сейчас произошло? Этот код создает приложение Vue на странице. Мы присоединяем его к элементу с помощью CSS-селектора #contents
.
Это относится к пустому элементу div
на странице. Теперь приложение настроено на использование Vue.js!
3.2. Отображение данных в шаблоне
Затем давайте создадим заголовок, который показывает атрибут « eventName
», который мы передали из контроллера Spring, и визуализируем его с использованием функций Thymeleaf:
<div class="lead">
<strong>Name of Event:</strong>
<span th:text="${eventName}"></span>
</div>
Теперь давайте добавим атрибут data
к приложению Vue для хранения нашего массива данных игрока, который представляет собой простой массив JSON.
Наше приложение Vue теперь выглядит так:
<script type="text/babel">
var app = new Vue({
el: '#contents',
data: {
players: [
{ id: "1",
name: "Lionel Messi",
description: "Argentina's superstar" },
{ id: "2",
name: "Christiano Ronaldo",
description: "World #1-ranked player from Portugal" }
]
}
});
</script>
Теперь Vue.js знает об атрибуте данных, называемом player
.
3.3. Визуализация данных с помощью компонента Vue.js
Затем давайте создадим компонент Vue.js с именем player-card,
который отображает только одного игрока
. Не забудьте зарегистрировать этот компонент перед созданием приложения Vue.
В противном случае Vue его не найдет:
Vue.component('player-card', {
props: ['player'],
template: `<div class="card">
<div class="card-body">
<h6 class="card-title">
{{ player.name }}
</h6>
<p class="card-text">
<div>
{{ player.description }}
</div>
</p>
</div>
</div>`
});
Наконец, давайте перейдем к набору игроков в объекте приложения и отобразим компонент карты игрока для каждого игрока:
<ul>
<li style="list-style-type:none" v-for="player in players">
<player-card
v-bind:player="player"
v-bind:key="player.id">
</player-card>
</li>
</ul>
Логика здесь заключается в директиве Vue, называемой v-for,
которая будет перебирать каждого игрока в атрибуте
данных player и отображать карточку
игрока для каждой записи игрока
внутри элемента <li>
.
v-bind:player
означает, что компоненту player-card
будет присвоено свойство player
, значением которого будет переменная цикла player
, с которой в данный момент работает. v-bind:key
необходим, чтобы сделать каждый элемент <li>
уникальным.
Как правило, player.id
— хороший выбор, поскольку он уже уникален.
Теперь, если вы перезагрузите эту страницу, посмотрите на сгенерированную HTML-разметку в devtools
, и она будет выглядеть примерно так:
<ul>
<li style="list-style-type: none;">
<div class="card">
// contents
</div>
</li>
<li style="list-style-type: none;">
<div class="card">
// contents
</div>
</li>
</ul>
Примечание об улучшении рабочего процесса: быстро станет обременительным перезапускать приложение и обновлять браузер каждый раз, когда вы вносите изменения в код.
Поэтому, чтобы облегчить жизнь, обратитесь к этой статье о том, как использовать инструменты разработки Spring Boot и
автоматический перезапуск.
4. Вывод
В этой быстрой статье мы рассмотрели, как настроить веб-приложение, используя Spring Boot для серверной части и Vue.js
для внешнего интерфейса. Этот рецепт может стать основой для более мощных и масштабируемых приложений, и это всего лишь отправная точка для большинства таких приложений.
Как обычно, образцы кода можно найти на GitHub .