{{ post.title }}
{{ post.body }}
{{ post.id }}
Одностраничные приложения (SPA) имеют мнжество преимуществ, таких как скорость, по-настоящему хороший UX, и полный контроль HTML-разметки. Становится всё больше и больше сайтов SPA; всё больше инструментов, которые упрощают процесс разработки SPA. Вы, вероятно уже читали о молодом и перспективном фреймворке Vue.js. Предлагаю вам глубже погрузиться в Vue и на конкретном примере разобраться с простым SPA.
Мы напишем клиент-серверное приложение простейшего блога. Приложение будет отображать список записей, а также полный текст каждой отдельной записи. И само собой, всё это будет происходить без перезагрузки страницы.
Ознакомившись с примером этого приложения, вы научитесь извлекать данные в Vue, создавать роуты и разберётесь с интересной особенностью Vue — однофайловыми компонентами.
В этом руководстве мы в основном сосредоточимся на фронтенде на Vue. Размышлять о написании REST бэкенда мы не будем. Для примера будет использоваться сервис jsonplaceholder.typicode.com предостовляющий заглушку в виде REST API.
Начать работу с Vue очень просто. С использованием правильных инструментов это ещё проще. Рекомендую взглянуть на проект vue-awesome, который содержит список инструментов, компонентов, библиотек и плагинов на все случаи жизни.
При создании нового проекта рекомендуется воспользоваться Vue-cli. Так можно создавать проекты с использованием официальных шаблонных проектов Vue, или одного из множества шаблонных проектов с открытым исходным кодом, и, конечно же, вы можете создать свой собственный и использовать его в любом месте.
Итак, для начала установим vue-cli в качестве глобального пакета:
$ npm install -g vue-cli
Затем проинициализируем проект с выбранным шаблоном; для нашего примера более чем достаточно использовать webpack-simple.
$ vue init webpack-simple vue-spa
Далее перейдём в папку vue-spa и запустим npm install в терминале. После установки всех пакетов, мы можем запустить наше приложение в режиме разработки.
$ npm run dev
Эта команда автоматически запустит наш проект на локальном dev-сервере webpack. В браузере появится наше простейшее приложение Vue. Конечно оно выглядит совсем не так, как бы нам хотелось, и годится лишь в качестве отправной точки для начала чего-то большего. Чтобы продолжить работу, предлагаю сначала ознакомиться со структурой нашего шаблона.
Внутри шаблон webpack-simple имеет следующую структуру:
Файл index.html содержит простую разметку HTML с единственным элементом «app» в body. Он будет заменён на DOM, сгенерированный vue. По этой причине тэг body не рекомендуется использовать в качестве корневого элемента.
В папке src лежит файл main.js, который содержит точку входа webpack. Компоненты Vue импортируются там же. Ещё там описан корневой экземпляр Vue, который пока что имеет два свойства. Свойство «el» обеспечивает экземпляру Vue связь с указанным DOM элементом. Ещё одно — функция отрисовки, генерирующая DOM из App.vue. В общем, это все, что нам нужно знать о структуре шаблона webpack-simple, не так много, не так ли? Основная часть нашего приложения будет запрограммирована в App.vue. Расширение .vue определяет файл как однофайловый компонент vue. Это одна из особенностей Vue с которой мы сейчас познакомимся поближе.
Каждый файл *.vue состоит из блоков трёх типов: ,
Остался заключительный шаг. Нам нужно отобразить содержимое записи поста. {{ post.body }} {{ post.id }}
Кроме того, можно добавить немного стилей, чтобы приложение выглядело лучше.
Код приложения хостится на github.com. Достаточно клонировать репозиторий и переключать ветку по номеру шага чтобы проследить разработку приложения шаг за шагом например: $ git checkout step-1
В настоящий момент нам абсолютно нечего отображать в нашей навигационной панели, поэтому давайте получим данные с сервера. Для этого я выбрал Axios — простой в использовании HTTP-клиент. Вы также можете использовать любой удобный для вас способ, например, Vue-ресурс или собственную выборку или даже jQuery Ajax.Шаг 2
Установим Axios$ npm install --save-dev axios
Затем импортируем его в компонент App и определим метод getAllPosts () который будет делать запрос к серверу и присваивать его свойству posts. Вызываем метод в хуке created (), который будет вызываться после создания экземпляра Vue и после установки настроек обращения к данным.import axios from 'axios'
export default {
data () {
return {
posts: null,
endpoint: 'https://jsonplaceholder.typicode.com/posts/',
}
},
created() {
this.getAllPosts();
},
methods: {
getAllPosts() {
axios.get(this.endpoint)
.then(response => {
this.posts = response.data;
})
.catch(error => {
console.log('-----error-------');
console.log(error);
})
}
}
}
А теперь отобразим все заголовки записей в боковой панели.
До сих пор мы отображали только заголовки записей, но пока мы ещё не можем видеть сами записи. Теперь необходимо отобразить полный пост в разделе контента в соответствии с выбранным названием на боковой панели. В то же время хотелось бы, чтобы каждая запись была доступна по своему уникальному адресу.Шаг 3
Для этого воспользуемся официальной Vue библиотекой vue-router. Как уже понятно из названия, библиотека позволяет настраивать роутинг для нашего приложения.
Установим библиотеку: $ npm install --save-dev vue-router
Для настройки роутинга вернёмся к файлу main.js. Здесь мы определим настройки роутинга и добавим их в наш экземпляр Vue.import Vue from 'vue'
import Router from 'vue-router'
import App from './App.vue'
import Post from './components/Post.vue'
import Hello from './components/Hello.vue'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
name:'home',
component: Hello,
},
{
path: '/post/:id',
name:'post',
component: Post,
props: true,
},
]
})
new Vue({
el: '#app',
render: h => h(App),
router
})
В настройках роутинга мы указали, какой компонент вызывает отрисовку по соответствующему пути. Поскольку только компонент Post.vue будет отвечать за отрисовку каждого поста, нам не потребуется определять путь к каждому посту, достаточно определить динамический путь.path: '/post/:id'
Этот путь содержит динамический сегмент : id который указывает на конкретный пост. При этом у нас есть доступ к этому сегменту в компоненте Post через this.$route.params.id. Однако использование $route в нашем компоненте закрепит жесткую связь с роутом, что в свою очередь ограничивает гибкость компонента, поскольку он может использоваться только на определенных URL-адресах. Вместо этого мы можем использовать опцию props и установить её в true. После этого $route.params станет связан с опцией props компонента Post.
Теперь, когда мы создали роутер, мы можем вернуться к нашему приложению и добавить еще несколько строк в шаблон.
Здесь мы имеем два компонента vue-router: Шаг 4
Перейдём к файлу Post.vue, в котором добавим простой шаблон:
{{ post.title }}
Затем нам нужно установить параметры экземпляра Vue для этого компонента. Здесь все также как в настройках отображения всех постов. Объявим опцию props с меняющимся id, которая будет получать номер нашего поста. Далее, объявим объект данных, как уже делали в App.vue: import axios from 'axios';
export default {
props: ['id'],
data() {
return {
post: null,
endpoint: 'https://jsonplaceholder.typicode.com/posts/',
}
}
}
Затем опишем метод getPost (), который будет получать только одну запись поста по идентификатору и вызовем его в хуке created ().methods: {
getPost(id) {
axios(this.endpoint + id)
.then(response => {
this.post = response.data
})
.catch( error => {
console.log(error)
})
}
},
created() {
this.getPost(this.id);
},
Почти готово. Если мы запустим приложение сейчас, мы увидим, что, хотя URL-адрес меняется, мы видим единственный пост, который был отрисован первым. Дело в том, что для отрисовки разных постов у нас есть один и тот же компонент, и Vue не нужно его пересоздавать из-за лишней траты ресурсов, а это также означает, что хуки жизненного цикла компонента не будут вызваны.
Чтобы это исправить, нам просто нужно установить watcher для объекта $route.watch: {
'$route'() {
this.getPost(this.id);
}
}
Теперь всё работает так, как и должно. Чтобы получить версию для продакшина достаточно выполнить команду npm run build в консоли. Подведём итоги
Мы написали простое одностраничное приложение с использованием Vue за четыре шага. Мы узнали, как легко начать свой проект с vue-cli. Мы рассмотрели концепцию однофайловых компонентов Vue, которые делают ваш проект более гибким и масштабируемым. Мы узнали, как извлекать данные из внешнего API с помощью Axios. И мы увидели, как настроить роутинг с помощью vue-router. Разумеется, это базовые знания, но я надеюсь, что это поможет вам начать использовать Vue.js используя его расширенные возможности.Полезные ссылки
→ Оригинал статьи
→ Ссылка на проект GitHub с исходным кодом из статьи
→ Проект vue-awesome