Введение

Переход на новый язык, библиотеку или фреймворк может быть пугающим, даже выполнение простых задач может поначалу показаться трудным. Привыкание к различным условностям требует времени, но настойчивость в конечном итоге окупится. Я твердо верю, что в мире веб-разработки мы должны быть открыты новому и учиться. При этом также важно делать осознанный выбор при принятии решения о том, что изучать, никто не может выучить все, и в нынешних условиях, когда мы видим новую среду Javascript каждую неделю, легко просто сидеть сложа руки и придерживаться того, что мы знаем. Особенно, если последние 10 лет мы спокойно писали в таком фреймворке, как jQuery. Я переключился на использование Vue или Vanilla Javascript пару лет назад (я только что начал небольшой проект с использованием Alpine), однако я все еще поддерживаю устаревший код jQuery в старых проектах. Когда я впервые перешел на Vue с jQuery, это не казалось таким естественным, и я думаю, что это нормально — в конце концов, я писал на jQuery много лет. Я должен отметить, что эта статья никоим образом не направлена ​​на то, чтобы очернить jQuery, я думаю, что это фантастическая библиотека и имеет свое место, но вместо этого она направлена ​​на помощь разработчикам jQuery, которые заинтересованы в изучении и/или лучшем понимании Vue.

Краткий обзор различий между Vue и jQuery

Первое различие между jQuery и Vue, которое следует отметить, — это библиотека и фреймворк. jQuery — это библиотека, это означает, что как разработчики мы отвечаем за то, где мы используем код библиотеки с нашим собственным кодом, Vue, с другой стороны, является фреймворком и предоставляет нам структуру, в которой мы можем разместить наш код, будь то быть состоянием, методами, хуками жизненного цикла или чем-то еще.

Например, мы можем увидеть экземпляр Vue, который выглядит примерно так:

<script>
    const app = new Vue({
        el: '#app', /*element*/

        data: { /*App data*/ },

        components: { /*Components*/ },

        computed: { /*Computed data*/ },

        methods: { /*App methods*/ },

        watch: { /*Watches data for change*/},

        created() { /*Called when app is created*/ },

        mounted() { /*Called when app is mounted*/ }
    })
</script>

el: определяет элемент DOM, на котором мы хотим инициировать наш экземпляр Vue.

data: объект, определяющий корневые данные нашего приложения (данные на уровне компонента — это функция, возвращающая объект).

components: компоненты, которые мы хотели бы использовать.

computed: Computed позволяет нам возвращать реактивные обработанные данные.

методы: как и следовало ожидать, это методы/функции, которые мы можем вызывать из нашего приложения.

watch: отслеживает изменения в наших данных.

Затем у нас есть 2 хука жизненного цикла, из которых мы можем вызывать методы, извлекать и устанавливать данные и т. д.:

created(): Created вызывается при создании нашего приложения.

mounted(): Mounted вызывается, когда наше приложение смонтировано.

Есть и другие зацепки и объекты жизненного цикла, с которыми мы столкнемся, в частности, когда будем глубже изучать компоненты. Но пока это дает нам простой обзор.

Запуск jQuery совсем другой:

<script>
    $(function () { //$(document).ready(function() {}
        //Code goes here
    })
</script>

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

Привет, мир в jQuery:

Мы начнем с простого «Hello world», в jQuery маловероятно, что мы будем использовать Javascript для заполнения нашего приложения «Hello world», поэтому мы не будем. В некоторых случаях мы отказываемся от Vue, но в этом примере это дает нам простое представление о выводе данных.

<main id="app">
    Hello world
</main>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
    $(function () { //$(document).ready(function() {}
    })
</script>

Так что же здесь происходит? Что ж, в jQuery мы инициировали наш экземпляр jQuery, но ничего с ним не сделали, вместо этого мы заполнили div в нашем редакторе словами «Hello world».

Привет, мир в Vue:

<main id="app">
    {{ message }}
</main>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello World'
        }
    })
</script>

С другой стороны, во Vue происходит немного больше — первое отличие, которое мы замечаем, это наличие {{ message }},это переменная, переменные в наших шаблонах заключены в фигурные скобки и связаны с нашим объектом data*, установленным в нашем экземпляре Vue. Если мы бросим взгляд на экземпляр Vue, то, конечно же, увидим свойство данных с ключом «сообщение» и значением «Привет, мир», которое мы видим в нашем приложении.

*Фигурные скобки также могут возвращать вычисляемые свойства и реквизиты, подробнее об этом позже.

Приложение Vue Hello world может быть не особенно захватывающим или даже практичным, но оно иллюстрирует основные варианты использования данных в наших приложениях.

Основные события в jQuery

Теперь, когда у нас есть общее представление о данных, мы можем посмотреть, как мы можем использовать данные вместе с методами для инициирования изменений в DOM. Обычная ситуация может заключаться в том, что у нас есть кнопка, и при нажатии на эту кнопку мы хотим добавить класс к элементу на странице. Итак, давайте создадим это в jQuery:

<style>
    .button.is-clicked {
        background: red;
    }
</style>
<main id="app">
    <button class="button">Click me</button>
</main>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
    $(function () { //$(document).ready(function() {}
        $('.button').on('click', function() {
            $(this).toggleClass('is-clicked');
        })
    })
</script>

Итак, в нашем новом приложении у нас есть кнопка, и когда мы нажимаем эту кнопку, мы хотим переключать класс .is-clicked, который включает и выключает красный фон. Мы выбираем наш класс кнопки и прикрепляем событие клика, которое вызывает метод jQuery .toggleClass().

Основные события в Vue

<style>
    .button.is-clicked {
        background: red;
    }
</style>
<main id="app">
    <button
        class="button"
        :class="{ 'is-clicked' : isClicked }"
        @click="onButtonClick"
    >
        Click me
    </button>
</main>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            isClicked: false
        },
        methods: {
            onButtonClick() {
                this.isClicked = !this.isClicked;
            }
        }
    })
</script>

Как и в нашем приложении Hello world, мы устанавливаем наши данные/состояние в объекте данных. Тем не менее, есть несколько вещей, которые мы не использовали раньше. Сначала давайте посмотрим на экземпляр Vue. Мы воспользовались преимуществами методовобъекта Vue и создали новый метод с именем onButtonClick(), который при при вызове установит для свойства данных isClicked противоположное логическое значение, переключаясь между false и true. Обратите внимание, что при ссылке на данные в экземпляре Vue мы должны использовать ключевое слово this k.

Теперь, когда мы разобрались с экземпляром Vue, давайте рассмотрим шаблон. Как и в нашем эквиваленте jQuery, у нас есть кнопка с классом .button, но у нас также есть 2 специальных атрибута и 2 специальных атрибута. : @click и :class. Атрибут @ и атрибут : являются сокращенными для v-on: и v-bind: соответственно. v-on:или @в нашем случае для привязки событий к элементу. В нашем приложении мы привязали обработчик события клика к нашей кнопке. При нажатии на кнопку вызывается метод onButtonClick(), установленный в объекте методов, который переключает логическое свойство данных для isClicked. v-bind: или :, как мы его использовали, для привязки данных к атрибуту в нашем В этом случае мы привязали наш isClickedbолин к классу .is-clicked, что означает, что когда наш isClicked имеет значение true, наш класс .is-clicked будет добавлен к нашему элементу.

Создание вкладок с помощью jQuery

Типичным примером работы с событиями и состоянием в реальном мире являются вкладки. Чтобы создать вкладки в jQuery, мы можем написать что-то вроде этого:

<style>
    .tab__content {
        display: none;
    }
    .tab__content.is-active {
        display: block;
    }
</style>
<main id="app">
    <button class="tab__button" data-tab="about">About</button>
    <button class="tab__button" data-tab="author">Author</button>
    <div class="tab__content is-active" data-tab="about">
        This article is a look at Vue for jQuery Developers
    </div>
    <div class="tab__content" data-tab="author">        
        This article is written by Liam Hall, see more about him here: <a href="wearethreebears.co.uk">Three Bears</a>
    </div>
</main>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
    $(function () { //$(document).ready(function() {}
        $('.tab__button').on('click', function() {
            let button = $(this);
            let tab = button.attr('data-tab');
            $('.tab__content').removeClass('is-active');
            $(`.tab__content[data-tab="${tab}"]`).addClass('is-active');
        })
    })
</script>

У нас здесь происходит несколько вещей:

Стиль: мы установили стиль содержимого вкладки, который не отображается, однако, если .is-active класс присутствует, мы будем отображать содержимое.

Разметка: у нас есть 2 кнопки с атрибутами data-tab и 2 блока контента с соответствующими data-tab, мы также пометили первый элемент .tab__content тегом .is- активныйкласс.

jQuery: мы прикрепляем к кнопкам событие щелчка, которое при инициации пользователем извлекает значение атрибута data-tab на кнопке перед удалением .is-active из всех экземпляров .tab__content перед поиском .tab__content элемент с соответствующим атрибутом data-tab и настройкой .is-active класс.

Создание вкладок с помощью Vue

Чтобы воспроизвести это поведение в Vue, мы могли бы сделать что-то вроде этого:

<main id="app">
    <button 
        class="tab__button"
        @click="onButtonClick('about')"
    >
        About
    </button>
    <button 
        class="tab__button"
        @click="onButtonClick('author')"
    >
        Author
    </button>
    <div class="tab__content" v-show="tab === 'about'">
        This article is a look at Vue for jQuery Developers
    </div>
    <div class="tab__content" v-show="tab === 'author'">
        This article is written by Liam Hall, see more about him here: <a href="wearethreebears.co.uk">Three Bears</a>
    </div>
</main>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            tab: 'about'
        },
        methods: {
            onButtonClick(tab) {
                this.tab = tab;
            }
        }
    })
</script>

Мы сразу замечаем, что нам больше не нужны стили для отображения и скрытия нашего активного контента, вместо этого можно обрабатывать условный рендеринг, в приведенном выше примере мы выбрали v-show хотя v-if также сработает в этом случае.

v-show ближе к нашей реализации jQuery, поскольку скрывает элемент с помощью CSS, а v-if является истинным условным выражением, удаляющим элемент из DOM, если оно ложно. Другие операторы условного рендеринга, которые мы ожидаем, также доступны в Vue: v-else, v-else-if и даже v-for для циклического просмотра контента.

Большая часть разметки похожа на нашу реализацию jQuery, но опять же, мы видим нашу директиву @, которая вызывает наш onButtonClick() method, который, в свою очередь, обновляет наше состояние, чтобы определить соответствующий контент для отображения пользователю.

На самом деле мы можем упростить это еще больше, наши директивы событий не должны вызывать функции, но фактически могут напрямую обновлять состояние:

<main id="app">
    <button 
        class="tab__button" 
        @click="tab = 'about'"
    >
        About
    </button>
    <button 
        class="tab__button" 
        @click="tab = 'author'"
    >
        Author
    </button>
    <div class="tab__content" v-show="tab === 'about'">
        This article is a look at Vue for jQuery Developers
    </div>
    <div class="tab__content" v-show="tab === 'author'">
        This article is written by Liam Hall, see more about him here: <a href="wearethreebears.co.uk">Three Bears</a>
    </div>
</main>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            tab: 'about'
        }
    })
</script>

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

Мы рассмотрели довольно много базовых функций Vue, но еще не увидели реальную мощь фреймворков. Одним из замечательных примеров того, что Vue делает так хорошо, является реактивность. Чтобы продемонстрировать это, мы рассмотрим простую форму. Когда мы вводим наше имя, имя и фамилию в предоставленные поля, DOM отобразит наше объединенное полное имя.

Чтобы построить это в jQuery, мы могли бы написать что-то вроде этого:

<main id="app">
    <h1>Full name:<span id="full-name"></span></h1>
    <form class="form">
        <label for="first-name">First name</label>
        <input type="text" id="first-name" name="first_name"/>
        <label for="last-name">Last name</label>
        <input type="text" id="last-name" name="last_name" />
    </form>
</main>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
    $(function () { //$(document).ready(function() {}
        $('.form').on('keyup', function() {
            let firstName = $('#first-name').val().trim();
            let lastName = $('#last-name').val().trim();
            $('#full-name').text(`${firstName} ${lastName}`);
        })
    })
</script>

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

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

<main id="app">
    <h1>Full name:{{ fullName }}</h1>
    <form class="form">
        <label for="first-name">First name</label>
        <input type="text" id="first-name" name="first_name" v-model.trim="firstName"/>
        <label for="last-name">Last name</label>
        <input type="text" id="last-name" name="last_name" v-model.trim="lastName" />
    </form>
</main>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    var app = new Vue({
         el: '#app',
         data: {
             firstName: '',
             lastName: ''
         },
         computed: {
              fullName() {
                  return `${this.firstName} ${this.lastName}`;
              }
         }
    })
</script>

Как и в примере с jQuery, у нас есть форма и выходные данные, однако на этот раз мы не помещаем прослушиватель в форму, вместо этого мы используем специальный атрибут с именем v-model , который мы можем прикрепить к свойству объекта данных. v-model является полностью реактивным, поэтому, когда мы обновляем ввод, наши данные автоматически обновляются, и, в отличие от примера jQuery, нам не нужно прикреплять событие для этого. для нас. Мы также прикрепили модификатор .trim к нашей v-модели. Vue предоставляет нам ряд полезные модификаторы, облегчающие нашу жизнь, в этом случае нам не нужно вызывать функцию .trim()для наших данных в методе.

Теперь у нас есть реактивные входные данные, и мы можем воспользоваться computed {}объектом функций, который возвращает обработанные данные. В нашем случае наше вычисляемое свойство fullName() возвращает наше объединенное полное имя, и, что самое приятное, как v-model, оно полностью реактивно.

К части 2:

Если вы нашли эту статью полезной, пожалуйста, хлопните в ладоши и подпишитесь на меня на Medium и/или в Twitter: @wearethreebears

Вы можете найти часть 2, где мы рассмотрим создание нашего первого компонента, работу с реквизитами и портирование всего, что мы сделали, в Vue CLI здесь.