Были времена, когда веб-приложения разрабатывались на JavaScript таким образом, что как и HTML, так и JavaScript и временами даже CSS, все писалось вместе и вперемешку, не было никакой строгой архитектуры и последовательности, код никак не разбивался на какие-нибудь отдельные части, что конечно же, делало всю разработку невыносимой. Такие времена прошли и сейчас используются различные библиотеки и фреймворки, позволяющий сделать разработку веб-приложений простой и качественной.

Одним из таких фреймворком является JavaScript фреймворк - Vue.js. О нем и поговорим в этой статье.

Vue (произносится как view - вью) - это прогрессивный фреймворк для создания пользовательских интерфейсов. Vue позволяет строить приложения с применением архитектурного паттерна MVVM (Model-View-ViewModel).

Особенность Vue.js в том, что его можно начинать с легкостью использовать в уже существующем приложени, внедряя постепенно и используя вместе с другими JavaScript библиотеками. Это очень отличная особенность, когда нужно переписать приложение постепенно, а не все сразу.

Создатель фрейморвка Vue.js - Эван Ю (Evan You), бывший сотрудник Google. Его фрейморк используют множество компаний, например,  Alibaba, Baidu & Tencent, Xiaomi. Разработка фреймворка ведется Эваном вместе с сообществом разработчиков вне всяких компаний.

Плюсы Vue.js

  • достаточно быстрая разработка
  • небольшой вес фреймворка
  • хороша документация
  • большое сообщество разработчиков
  • быстрое взаимодействие с виртуальным DOM
  • подключение плагинов и создание своих плагинов
  • компонентная разработка приложения
  • реализует современные подходы к разработке
  • поддержка серверного рендинга приложения с помощью Nuxt.js

Концепции фрейморвка

Основными концепциями Vue являются:

  • реактивность
  • экземпляр
  • компоненты
  • директивы
  • анимация и переходы
     

Реактивность

В этом фрейморвке используются идеи - реактивного программирования. Реактивное программирование - это когда разработка основана на потоках статических и динамических данных, а также распространении изменений благодаря потоку этих данных.

Экземпляр

С создания экземпляра Vue начинается вся разработка. Экземпляр создается через функцию:

var vm = new Vue({
  // опции
})

Для экземпляра указывается объект с набором опций, используемых в приложении.

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data () {
    return {
      obj
    }
  }
})

Все компоненты Vue также являются экземплярами Vue и поэтому также принимают объект параметров.

Компоненты

Компоненты - это разделение кода, его инкапсулирование, на независимые части позволяющие повторно использовать код. Компоненты образуют древовидную иерархию.

Разделение программного кода на некие отдельные компоненты, которые потом взаимодействуют между собой, хорошее решение при построении качественных приложений. Такие приложения легче поддерживать, ведь код каждого компонента написан так, чтобы было как можно меньше зависимостей между компонентами. Ведь когда первый код зависит от второго, и в этом втором, что-то поменялось, то можно ожидать, что в первом коде что-то пойдет не так как ожидалось.
Vue.js позвляет разделять весь код приложения на компоненты и даже асинхронно загружать необходимый компонент в нужный момент. 

Можно представить 3 вида разделения кода приложения:

  • постраничное разделение
  • разделение вне видимости
  • разделение по условию

1. Постраничное разделение кода

Разделение кода постранично производится когда в приложении используется несколько страниц, то есть, ваше приложение не одностраничное. За каждую страницу отвечает отдельный компонент, а сборка файлов с этими компонентами происходит через функцию import. При перемещении между страницами, нужные файлы будут асинхронно подгружаться. Такое поведение можно сделать с помощью роутинга Vue.js.

Простой пример роутинга может выглядеть следующим образом:

const NotFound = { template: '<p>Страница не найдена</p>' }
const Home = { template: '<p>главная</p>' }
const About = { template: '<p>о нас</p>' }

const routes = {
  '/': Home,
  '/about': About
}

new Vue({
  el: '#app',
  data: {
    currentRoute: window.location.pathname
  },
  computed: {
    ViewComponent () {
      return routes[this.currentRoute] || NotFound
    }
  },
  render (h) { return h(this.ViewComponent) }
})

2. Разделение кода вне видимости

Разделение кода приложения вне видимости - это когда есть какая-та часть, которую нужно отобразить лишь в тот момент, когда другая часть находится за пределами отображаемой, то есть видимой на данный момент, части приложения. Например, ваше приложение отобразило на экране 5 постов, при прокрутке чуть ниже, приложение подгружает асинхронно еще 5 постов, и так далее. Это очень нужная вещь, которая позволяет экономить ресурсы приложения, сделав его производительней в работе.

3. Разделение кода по условию

Когда какая-то часть приложения должна отображаться в зависимости от состояния какого-либо элемента или выполнения действия, то можно использовать разделение кода по условию. Например, если пользователь находится в одной группе, то ему можно подгружать один тип контента, если пользователь во второй группе, то соответственно ему отображаем другой тип контента и так далее. Сюда же можно отнести какие-либо всплывающие окна, вкладки, отображение элементов в зависимости от состояния различных переключателей.

Директивы

Директивы - специальные атрибуты с префиксом v-. В качестве значения атрибуты принимают одно выражение JavaScript (кроме v-for). Директива реактивно применяет к DOM изменения при обновлении значения этого выражения. 

<p v-if="seen">Сейчас меня видно</p>

В примере директива v-if удалит или вставит элемент <p> в зависимости от истинности значения выражения seen.

Анимация и переходы

Vue позволяет анимировать переходы при добавлении, обновлении и удалении объектов DOM.

  • автоматически использовать CSS-классы для анимаций и переходов
  • интегрировать сторонние библиотеки CSS-анимаций, например, animate.css
  • использовать JavaScript для работы с DOM напрямую в transition-хуках
  • интегрировать сторонние библиотеки JavaScript-анимаций, например, Velocity.js

Система анимирования переходов Vue предоставляет много простых методов для анимации появления и исчезновения элементов и списков, а также анимации самих данных. Например:

  • чисел и арифметических выражений
  • отображаемых цветов
  • позиции SVG-элементов
  • размеров и прочих свойств элементов

Все эти параметры либо хранятся как числа, либо могут быть сконвертированы в числа. Это значит, что мы можем использовать сторонние библиотеки для анимации, в сочетании с компонентными и реактивными системами Vue.

Анимация состояния при помощи наблюдателей позволяют нам анимировать изменения любых числовых свойств. В такой абстрактной форме это может звучать сложновато, так что давайте просто разберём пример с использованием Tween.js:

<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>

<div id="animated-number-demo">
  <input v-model.number="number" type="number" step="20">
  <p>{{ animatedNumber }}</p>
</div>
new Vue({
  el: '#animated-number-demo',
  data: {
    number: 0,
    animatedNumber: 0
  },
  watch: {
    number: function(newValue, oldValue) {
      var vm = this
      function animate () {
        if (TWEEN.update()) {
          requestAnimationFrame(animate)
        }
      }

      new TWEEN.Tween({ tweeningNumber: oldValue })
        .easing(TWEEN.Easing.Quadratic.Out)
        .to({ tweeningNumber: newValue }, 500)
        .onUpdate(function () {
          vm.animatedNumber = this.tweeningNumber.toFixed(0)
        })
        .start()

      animate()
    }
  }
})

Как и для анимированных компонентов, данные, на которых основываются переходы, могут обновляться в режиме реального времени, что особенно полезно для прототипирования! Даже используя простой SVG-полигон можно достичь многих интересных эффектов, труднодостижимых без небольшой игры с переменными.