Замена jQuery на Vue.js: шаг сборки не требуется

Опубликовано: 2022-03-10
Краткая сводка ↬ Знаете ли вы, что вы можете включить Vue в свой проект так же, как вы включили бы jQuery — без необходимости сборки? Давайте рассмотрим некоторые распространенные варианты использования jQuery и то, как мы можем переключить их на Vue, и почему мы вообще хотим это сделать.

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

Некоторые люди могут не знать, что вы можете включить Vue в свой проект так же, как вы включили бы jQuery, без необходимости в сборке. Vue гибок в том смысле, что мы можем использовать его непосредственно в HTML.

Итак, если ваша текущая структура страницы выглядит так:

 <main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> //some jquery code here </script>

Вы можете буквально изменить тег сценария здесь и по-прежнему использовать HTML и JS в тандеме, как и раньше, рефакторинг лишь нескольких небольших фрагментов кода. Вам не нужно переписывать HTML на JavaScript, вам не нужно использовать webpack и вам не нужно настраивать гигантскую систему:

 <main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script> <script> //some vue code here </script>

Вы можете заменить теги и оставить разметку как есть. Самое приятное то, что вы можете подумать, что код станет более сложным, но, прочитав эту статью и увидев примеры, вы обнаружите, что Vue чрезвычайно прост, разборчив, его легко поддерживать и адаптировать. С точки зрения размера, они также довольно сопоставимы — чтобы использовать их как есть из CDN, минифицированная версия Vue 2.5.3 составляет 86 КБ . jQuery 3.2.1 весит 87 КБ .

Давайте рассмотрим некоторые распространенные варианты использования jQuery, а также то, как мы можем переключить их на Vue и почему мы вообще хотим это сделать.

Захват пользовательского ввода

Действительно распространенным вариантом использования JavaScript на сайте является захват пользовательского ввода из формы, поэтому давайте начнем с него. На самом деле мы пока не будем включать полную форму в интересах простоты и ясности, но мы доработаем ее к концу.

Чтобы собирать информацию по мере того, как пользователь вводит, вот как мы будем делать это в jQuery и Vue — параллельно:

См. информацию о захвате Pen jQuery из формы, введенной Сарой Драснер (@sdras) на CodePen.

См. информацию о захвате Pen jQuery из формы, введенной Сарой Драснер (@sdras) на CodePen.
 <div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
 // this is an alias to $(document).ready(function() { $(function() { //keypress wouldn't include delete key, keyup does. We also query the div id app and find the other elements so that we can reduce lookups $('#app').keyup(function(e) { var formname = $(this).find('.formname'); //store in a variable to reduce repetition var n_input = $(this).find('#thing').val(); formname.empty(); formname.append(n_input); }); }); 

См. информацию о захвате Pen Vue из формы, введенной Сарой Драснер (@sdras) на CodePen.

См. информацию о захвате Pen Vue из формы, введенной Сарой Драснер (@sdras) на CodePen.
 <div> <label for="name">Name:</label> <input type="text" v-model="name" /> <!--v-model is doing the magic here--> <p>{{ name }}</p> </div>
 //this is a vue instance new Vue({ //this targets the div id app el: '#app', data: { name: '' //this stores data values for 'name' } })

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

Вы также можете видеть, что в версии jQuery DOM находится под контролем — мы извлекаем данные из DOM, прослушиваем их и отвечаем на них. Это привязывает нас к тому, как в настоящее время настроен DOM, и заставляет нас думать о том, как его пройти. Если бы структура HTML-элементов изменилась, нам пришлось бы адаптировать наш код, чтобы он соответствовал этим изменениям.

В версии Vue мы храним состояние — мы отслеживаем одно свойство, которое хотим обновить и изменить, и отслеживаем элемент, который хотим изменить, с помощью вещи, называемой директивой. Это означает, что он прикреплен непосредственно к HTML-элементу, на который нам нужно настроить таргетинг. Структура DOM может измениться, HTML может перемещаться, и ничто из этого не повлияет на нашу производительность или захват этих событий. В нашем случае мы используем этот атрибут v-model на входе для подключения к данным, которые мы храним в JavaScript.

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

Еще после прыжка! Продолжить чтение ниже ↓

Сохранение пользовательского ввода в одном событии

Что интересно в том, как работает Vue, так это то, что он не связан с необходимостью думать о конкретных событиях DOM при сохранении и извлечении данных. По сути, у нас уже есть представление о том, что мы хотим запечатлеть; мы придаем ему форму, выбирая событие, с помощью которого его можно изменить. Напротив, jQuery тесно связан с тем, что делает DOM, и основывается на этих событиях DOM для создания хранимых переменных, которые могут быть размещены где угодно, а не в одной согласованной группе (в данных) для поиска. Мы можем видеть это в обновленной версии последнего примера, где информация собирается при нажатии клавиши ввода:

См. информацию о захвате данных Pen jQuery из ввода формы при вводе Сарой Драснер (@sdras) на CodePen.

См. информацию о захвате данных Pen jQuery из ввода формы при вводе Сарой Драснер (@sdras) на CodePen.
 <div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
 // this is an alias to $(document).ready(function() { $(function() { //We query the div id app and find the other elements so that we can reduce lookups $('#app').change(function(e) { var n_input = $(this).find('#thing').val(); $(this).find('.formname').append(n_input); }); }); 

См. информацию о захвате Pen Vue из ввода формы, ключ ввода от Сары Драснер (@sdras) на CodePen.

См. информацию о захвате Pen Vue из ввода формы, ключ ввода от Сары Драснер (@sdras) на CodePen.
 <div> <label for="name">Name:</label> <input type="text" v-model.lazy="name" /> <p>{{ name }}</p> </div>
 new Vue({ el: '#app', data: { name: '' } });

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

«Иди, возьми этот элемент, посмотри, что он делает, сохрани эти изменения, сделай что-нибудь с этими изменениями».

Для сравнения: в Vue мы контролируем то, что меняется, и DOM реагирует на эти изменения на основе наших команд. Мы прикрепляем его непосредственно к тому, что хотим обновить. В нашем случае у нас есть небольшая абстракция, называемая модификатором: v-model.lazy . Vue теперь знает, что не следует начинать сохранять это до тех пор, пока не произойдет событие изменения. Довольно аккуратно!

Переключение классов

Следующее, что мы рассмотрим, — это переключение классов CSS, потому что, как сообщил мне всемогущий, постоянно наблюдающий за мной Googly, это самая распространенная функциональность jQuery.

См. класс jQuery Pen Toggle от Сары Драснер (@sdras) на CodePen.

См. класс jQuery Pen Toggle от Сары Драснер (@sdras) на CodePen.
 <div> <button aria-pressed="false">Toggle me</button> <p class="toggle">Sometimes I need to be styled differently</p> </div>
 .red { color: red; } JS $(function() { $('button').click(function(e) { $('.toggle').toggleClass('red'); $(this).attr('aria-pressed', ($(this).attr('aria-pressed') == "false" ? true : false)); }); }); 

См. Pen Toggle Class Vue Сары Драснер (@sdras) на CodePen.

См. Pen Toggle Class Vue Сары Драснер (@sdras) на CodePen.
 <div> <button @click="active = !active" :aria-pressed="active ? 'true' : 'false'">Toggle me</button> <p :class="{ red: active }">Sometimes I need to be styled differently</p> </div>
 .red { color: red; } JS new Vue({ el: '#app', data: { active: false } })

Опять же, здесь мы видим, что в версии jQuery мы сохраняем состояние в DOM. У элемента есть класс, и jQuery принимает решение на основе наличия класса, который он проверяет, пингуя DOM. В версии Vue мы сохраняем условие и стилизуем его в соответствии с этим состоянием. Мы не запрашиваем эту информацию у DOM, мы храним ее сами.

Мы сохраняем active значение в данных, кнопка переключает условие, и .red изменяется в зависимости от этого условия. Даже состояния доступности, aria-pressed , задаются гораздо быстрее, так как нам не нужно ничего устанавливать в скрипте Vue, мы можем переключаться между состояниями непосредственно в шаблоне на основе состояния ' active .'

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

Скрытие и показ

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

См. скрытие шоу Pen jQuery от Сары Драснер (@sdras) на CodePen.

См. скрытие шоу Pen jQuery от Сары Драснер (@sdras) на CodePen.
 <div> <button type="button" aria-expanded="false"> Toggle Panel </button> <p class="hello">hello</p> </div>
 $(function() { $('#toggle').on('click', function() { $('.hello').toggle(); $(this).attr('aria-expanded', ($(this).attr('aria-expanded') == "false" ? true : false)); }); }); 

Посмотрите шоу Pen Vue от Сары Драснер (@sdras) на CodePen.

Посмотрите шоу Pen Vue от Сары Драснер (@sdras) на CodePen.
 <div> <button @click="show = !show" :aria-expanded="show ? 'true' : 'false'"> Toggle Panel </button> <p v-if="show">hello</p> </div>
 new Vue({ el: '#app', data: { show: true } })

И jQuery, и Vue отлично справляются с этой задачей, но есть пара причин, по которым я действительно работаю с Vue для чего-то вроде переключателя. У Vue есть инструмент под названием Vue devtools. Это мало чем отличается от инструментов разработки Chrome, но когда мы его используем, мы получаем особую информацию о том, что происходит с Vue.

Как в версии jQuery, так и в версии Vue мы видим, что элемент скрывается и появляется. Но что, если что-то пойдет не так? Что, если что-то в нашем коде работает не так, как мы ожидали? Чтобы начать отладку с помощью jQuery, мы, вероятно, добавим несколько console.log или установим несколько точек останова, чтобы попытаться отследить, где возникают ошибки.

Итак, в console.log нет ничего плохого, но с помощью инструментов разработки Vue мы действительно можем получить практический опыт Vue (не мог устоять) о том, что, по мнению Vue, происходит. На этом gif ниже вы можете видеть, как мы переключаем кнопку, инструменты разработки Vue соответственно обновляют состояние true/false. Если бы DOM когда-либо работал не так, как мы ожидали, мы могли бы видеть данные в Vue в режиме реального времени. Это значительно упрощает отладку; это на самом деле очень замечательно.

данные в режиме реального времени

Еще мне нравится то, что v-if легко распространить на другие условия. Я могу решить использовать вещь под названием v-show вместо v-if , если вещь, которую я переключаю, будет часто показывать и скрывать: v-if полностью размонтирует элемент, а v-show просто переключит его видимость. Это различие действительно важно, потому что гораздо эффективнее переключать видимость в стиле, чем полностью размонтировать/монтировать узел DOM. Я могу показать или скрыть что-то в зависимости от множества условий или даже от наличия пользовательского ввода или других условий. Обычно здесь jQuery может немного запутаться, пингуя DOM в нескольких местах и ​​координируя их. Ниже приведен пример координации показа чего-либо на основе ввода данных пользователем:

См. кнопку Pen Show на основе контента Vue Сары Драснер (@sdras) на CodePen.

См. кнопку Pen Show на основе контента Vue Сары Драснер (@sdras) на CodePen.
 <div> <label for="textarea">What is your favorite kind of taco?</label> <textarea v-model="tacos"></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
 new Vue({ el: '#app', data() { return { tacos: '' } } }) 

См. кнопку Pen Show на основе содержимого jQuery Сары Драснер (@sdras) на CodePen.

См. кнопку Pen Show на основе содержимого jQuery Сары Драснер (@sdras) на CodePen.
 <div> <label for="textarea">What is your favorite kind of taco?</label> <textarea></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
 $(function() { var button = $('.button'); var textarea = $('#textarea'); button.hide(); textarea.keyup(function() { if (textarea.val().length > 0) { button.show(); } else { button.hide(); } }) });

В этом примере вы можете увидеть ценность того, что Vue удерживает состояние — мы реагируем на изменения очень естественно и с меньшим количеством кода. Как только вы привыкнете к стилю, его станет легче понять, потому что вам не нужно прослеживать логику строка за строкой. Многие люди называют это различие «императивным и декларативным».

Отправка формы

Исторически каноническим вариантом использования jQuery была отправка формы с вызовом AJAX, поэтому мы должны взглянуть и на это. Vue на самом деле не имеет встроенной функции, такой как AJAX; в приложении Vue типично использовать что-то вроде Axios (библиотека JavaScript для выполнения HTTP-запросов), чтобы помочь с этой задачей.

Этот пример немного сложнее остальных. Здесь мы собираемся сделать несколько вещей:

  1. Кнопка будет серой до того, как мы начнем вводить форму, затем она получит класс «активный» и станет синей;
  2. Когда мы отправляем форму, страница не загружается;
  3. Когда форма будет отправлена, мы покажем данные ответа на странице.

См. AJAX отправки формы Pen jQuery от Сары Драснер (@sdras) на CodePen.

См. AJAX отправки формы Pen jQuery от Сары Драснер (@sdras) на CodePen.
 <div> <form action="/"> <div> <label for="name">Name:</label><br> <input type="text" name="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" name="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea name="caps" required></textarea> </div> <button class="submit" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre class="response"></pre> </div> </form> </div>
 $(function() { var button = $("button"); var name = $("input[name=name]"); name.keyup(function() { if (name.val().length > 0) { button.addClass('active'); } else { button.removeClass('active'); } }); $("form").submit(function(event) { event.preventDefault(); //get the form data var formData = { name: $("input[name=name]").val(), email: $("input[name=email]").val(), caps: $("input[name=caps]").val() }; // process the form $.ajax({ type: "POST", url: "//jsonplaceholder.typicode.com/posts", data: formData, dataType: "json", encode: true }).done(function(data) { $(".response") .empty() .append(JSON.stringify(data, null, 2)); }); }); });

Здесь мы увидим строки 2-10, связанные с обработкой класса кнопки, аналогично тому, как мы делали это раньше. Мы передаем в форму параметр с именем event, а затем произносим event.preventDefault() , чтобы избежать перезагрузки страницы. Затем мы собираем все данные формы из входных данных формы, обрабатываем форму, а затем помещаем ответ в .done() из запроса AJAX.

См. отправку формы Pen Vue Сарой Драснер (@sdras) на CodePen.

См. отправку формы Pen Vue Сарой Драснер (@sdras) на CodePen.
 <div> <form @submit.prevent="submitForm"> <div> <label for="name">Name:</label><br> <input type="text" v-model="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" v-model="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea v-model="caps" required></textarea> </div> <button :class="[name ? activeClass : '']" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre>{{ response }}</pre> </div> </form> </div>
 new Vue({ el: '#app', data() { return { name: '', email: '', caps: '', response: '', activeClass: 'active' } }, methods: { submitForm() { axios.post('//jsonplaceholder.typicode.com/posts', { name: this.name, email: this.email, caps: this.caps }).then(response => { this.response = JSON.stringify(response, null, 2) }) } } })

В версии Vue мы решаем, какие поля нам нужно заполнить в форме, а затем присоединяем их к той v-модели, которую мы использовали ранее. Мы проверяем наличие имени, чтобы переключить класс. Вместо того, чтобы передавать событие и писать event.preventDefault() , все, что нам нужно сделать, это написать @submit.prevent в нашем элементе формы, и мы позаботимся об этом. Чтобы отправить сам пост, мы используем Axios и сохраним ответ в экземпляре Vue.

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

Заключение

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

Благодаря гибкости Vue также легко перевести этот код на шаг сборки и структуры компонентов, если вы хотите со временем принять более сложную структуру. На самом деле довольно интересно попробовать это, поэтому, когда вы будете готовы сделать это, проверьте vue-cli. Что делает этот инструмент, так это дает вам возможность создать всю сборку Vue и веб-пакета производственного уровня с помощью всего нескольких команд терминала. Это позволяет вам работать с однофайловыми компонентами, где вы можете использовать HTML, CSS и Script в тандеме в одном файле, который составляет единые повторно используемые компоненты. Вам не нужно настраивать сборку веб-пакета, если вы не хотите делать что-то особенное, поэтому вы экономите много времени на настройке. У них даже есть встроенная команда для подготовки всего к производственному развертыванию.

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