- PVSM.RU - https://www.pvsm.ru -
Привет! Представляю вашему вниманию перевод статьи Vue.js Tutorial: From jQuery to Vue.js [1] автора Paul Redmond [2].
Что касается библиотек JavaScript, то никогда не было более популярной библиотеки, чем jQuery. Она создавалась для обхода DOM элементов с использованием CSS селекторов в то время, когда совместимость браузеров была важной проблемой для разработчиков.
Фактически jQuery настолько универсален, что я подумал что он отлично передаст то, почему я люблю писать UI с Vue, используя компонентный JavaScript. В этом руководстве мы сначала рассмотрим создание пользовательского интерфейса с jQuery, а затем перепишем его с помощью Vue.
Довольно типично, когда есть форма на которую требуется динамически добавить несколько полей с помощью JavaScript. Представьте, что у нас есть онлайн-форма оформления, которая позволяет пользователю приобретать несколько билетов, для которых требуется имя и адрес электронной почты для каждого билета:
Реализация этого сначала на jQuery является хорошим шагом, прежде чем мы сделаем то же самое с помощью Vue. Многие разработчики знакомы с jQuery и он обеспечивает отличный контраст с очень отличающимся подходом, который вы должны использовать для создания динамических интерфейсов.
Я создал примеры кода с использованием jQuery [3] и с использованием Vue [4] на Code Pen.
Есть дюжина способов которыми мы могли бы построить этот интерфейс с помощью jQuery. Например, мы могли бы создать форму с одним набором полей в HTML разметке, а затем позволить jQuery взять на себя динамическое добавление дополнительных полей в DOM, когда пользователь добавит больше.
Мы могли бы также использовать тег <script type = "text/template">
в качестве шаблона строки и добавить один по умолчанию в DOMContentLoaded, это подход который мы будем использовать.
Использование шаблона больше соответствует тому, как мы могли бы создать компонент в Vue. Вот как выглядит разметка HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>jQuery Checkout UI</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<style type="text/css">
body {
margin: 3em
}
button {
cursor: pointer;
}
.unit-price {
margin-right: 2rem;
color: #999;
}
</style>
</head>
<body>
<div class="container" id="app">
<form>
<!-- A placeholder for the list of attendee inputs -->
<div class="attendee-list"></div>
<div class="row justify-content-center">
<div class="col-sm-6"></div>
<div class="col-sm-2">
<button type="button" class="btn btn-secondary add-attendee">Add Attendee</button>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-sm-6">
<!-- A placeholder for the unit price -->
<span id="unit-price" class="unit-price"></span>
</div>
<div class="col-sm-2 text-left">
<button type="submit" id="checkout-button" class="btn btn-primary">
Pay
<!-- A placeholder for the checkout total -->
<span class="amount"></span></button>
</div>
</div>
</form>
</div>
<script type="text/template" data-template="attendee">
<div class="attendee row justify-content-center">
<div class="col-sm-3">
<div class="form-group">
<label class="sr-only">Name</label>
<input
class="form-control"
placeholder="Enter name"
name="attendees[][name]"
required>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label class="sr-only">Email address</label>
<input
type="email"
class="form-control"
placeholder="Enter email"
name="attendees[][email]"
required>
</div>
</div>
<div class="col-sm-2 text-left">
<button type="button" class="btn btn-light remove-attendee">
<span aria-hidden="true">×</span> Remove
</button>
</div>
</div>
</script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="app.js"></script>
</body>
</html>
Мы используем бета-версию Bootstrap 4 для макета. Мы определили несколько заполнителей jQuery, которые будут заполнены данными в $(document).ready(), но из разметки трудно сказать что произойдет. Вам нужно будет смотреть HTML и JavaScript одновременно, чтобы понять смысл предполагаемой функциональности. Возвращение к этому проекту через несколько месяцев потребует приличного количества умственных усилий, чтобы выяснить что происходит.
В нашем файле app.js мы будем заполнять цену за один билет и общую цену, которая будет отображаться с помощью JavaScript на кнопке проверки. Каждый раз, когда пользователь нажимает кнопку «Add Attendee», мы добавим новую строку в контейнер <div class="attendee-list"></div>
из шаблона.
Чтобы заполнить список участников повторяющимися полями формы, мы используем тег
Рядом с закрывающим тегом используем последнюю версию jQuery и app.js, в котором мы начнем работу с динамическими обновлениями пользовательского интерфейса.
Чтобы начать создавать нашу версию с jQuery, давайте инициализируем форму, вычислим общую сумму, добавим строку по умолчанию и установим цену из data:
// app.js
$(document).ready(function () {
var data = {
cost: 9.99
};
/**
* Get the attendee count
*/
function getAttendeeCount() {
return $('.attendee-list .row.attendee').length;
}
function addAttendee() {
$('.attendee-list').append(
$('script[data-template="attendee"]').text()
);
}
function syncPurchaseButton() {
// Total up the count for the checkout button total
$('#checkout-button span.amount').html(
'$' + data.cost * getAttendeeCount()
);
}
//
// Initialize the form
//
// Set up the unit cost of one ticket
$('#unit-price').html('$' + data.cost + ' ea.');
// Add one attendee by default on init
addAttendee();
syncPurchaseButton();
});
Первая часть кода устанавливает литерал [5] объекта data, содержащий одно свойство цены. Цена — это цена одного билета. Возможно, вы захотите установить цену одного билета динамически, но для наших целей она просто захардкожена.
У нас есть несколько вспомогательных функций, включая получение количества участников с помощью DOM query. Использование DOM является единственным точным способом определения этого значения с помощью jQuery.
Вторая вспомогательная функция добавляет нового участника в список, используя шаблон в нашей разметке.
Функция syncPurchaseButton() использует getAttendeeCount() для вычисления и заполнения кнопки покупки конечной суммой.
Если вы хотите получить такую же сумму покупки в любом месте шаблона, вам нужно будет синхронизировать все экземпляры в DOM с помощью селектора классов, но в данном случае мы нацелены только на один.
Если вы загрузите страницу в этот момент, форма будет инициализирована одним посетителем, ценой одного билета и общей суммой в кнопке проверки:
Затем давайте рассмотрим возможность добавления и удаления участников. jQuery имеет отличную обработку событий, включая запуск пользовательских событий. Начнем с кода, необходимого для добавления новых участников:
function addAttendee() {
$('.attendee-list').append(
$('script[data-template="attendee"]').text()
);
// Sync remove button UI
syncRemoveButtons();
}
function syncRemoveButtons() {
// If only one attendee, hide the first remove button
// otherwise, show all remove buttons
if (getAttendeeCount() === 1) {
$('.attendee-list .attendee .remove-attendee').first().hide();
} else {
$('.attendee-list .attendee .remove-attendee').show();
}
}
function syncPurchaseButton() {
// Total up the count for the checkout button total
$('#checkout-button span.amount').html(
'$' + data.cost * getAttendeeCount()
);
}
// Events
$('.add-attendee').on('click', function (event) {
event.preventDefault();
addAttendee();
$(this).trigger('attendee:add');
}).on('attendee:add', function () {
syncPurchaseButton();
syncRemoveButtons();
});
Функция syncRemoveButtons() гарантирует, что пользователь не сможет удалить поле когда оно остаётся только одно, но пользователь может удалить любую строку, если их несколько.
Теперь мы вызываем syncRemoveButtons() в функции addAttendee(), что означает, что если вы обновляете страницу, кнопка удаления скрыта, потому что количество участников — только один.
Обработчик события добавления участника вызывает функцию addAttendee(), а затем запускает пользовательское событие attendee:add.
В обработчике пользовательских событий мы синхронизируем общую цену, чтобы в кнопке она была правильной, а затем мы вызываем syncRemoveButtons(), чтобы обновить статус кнопки удаления, как описано выше.
Состояние синхронизации может выйти из-под контроля, так как ваш пользовательский интерфейс jQuery растет. Мы должны явно управлять состоянием и синхронизировать его, когда оно изменяется реагируя на события, и мы должны понимать особенности синхронизации состояний в каждом приложении.
Управление состоянием в jQuery требует дополнительных умственных усилий, потому что его можно обрабатывать и связывать с DOM различными способами. Когда состояние зависит от DOM, а не наоборот, DOM запросы для отслеживания состояния усложняются.
На этом этапе, если вы обновите страницу, вы можете добавить новые строки в форму. Когда вы добавите первого дополнительного участника, кнопка удаления будет показана для каждой строки, что позволит удалить строку.
Затем давайте подключим событие удаления и убедимся, что состояние пользовательского интерфейса отображается после удаления:
// Attach an event handler to the dynamic row remove button
$('#app').on('click', '.attendee .remove-attendee', function (event) {
event.preventDefault();
var $row = $(event.target).closest('.attendee.row');
$row.remove();
$('#app').trigger('attendee:remove');
});
$('#app').on('attendee:remove', function () {
syncPurchaseButton();
syncRemoveButtons();
});
Мы добавили click event listener на идентификатор DOM #app, который позволяет нам динамически реагировать на событие click для новых строк. Внутри этого обработчика мы предотвращаем событие кнопки по умолчанию, а затем находим ближайшего предка .row в дереве DOM.
Как только найден родитель $row, мы удаляем его из DOM и запускаем пользовательское событие attendee:remove.
В обработчике события attendee:remove мы синхронизируем нашу кнопку покупки и состояние кнопки удаления.
На данный момент у нас есть рабочий jQuery прототип UI нашей формы, который мы можем использовать для сравнения с Vue версией .
Вот полный файл app.js:
$(document).ready(function () {
var data = {
cost: 9.99
};
/**
* Get the attendee count
*/
function getAttendeeCount() {
return $('.attendee-list .row.attendee').length;
}
function addAttendee() {
$('.attendee-list').append(
$('script[data-template="attendee"]').text()
);
syncRemoveButtons();
}
function syncRemoveButtons() {
// If only one attendee, hide the first remove button
// otherwise, show all remove buttons
if (getAttendeeCount() === 1) {
$('.attendee-list .attendee .remove-attendee').first().hide();
} else {
$('.attendee-list .attendee .remove-attendee').show();
}
}
function syncPurchaseButton() {
// Total up the count for the checkout button total
$('#checkout-button span.amount').html(
'$' + data.cost * getAttendeeCount()
);
}
// Events
$('.add-attendee').on('click', function (event) {
event.preventDefault();
addAttendee();
$(this).trigger('attendee:add');
}).on('attendee:add', function () {
syncPurchaseButton();
syncRemoveButtons();
});
// Attach an event handler to the dynamic row remove button
$('#app').on('click', '.attendee .remove-attendee', function (event) {
event.preventDefault();
var $row = $(event.target).closest('.attendee.row');
$row.remove();
$('#app').trigger('attendee:remove');
});
$('#app').on('attendee:remove', function () {
syncPurchaseButton();
syncRemoveButtons();
});
//
// Initialize the form
//
// Set up the unit cost of one ticket
$('#unit-price').html('$' + data.cost + ' ea.');
// Add one attendee by default on init
addAttendee();
syncPurchaseButton();
});
Цель этого примера — показать вид пользовательского интерфейса, которой вы, вероятно, написали, и затем показать, как он выглядит в сравнении с Vue.js. Важным выводом здесь является состояние, привязанное непосредственно к DOM, и вы должны запросить DOM, чтобы делать вывод о состоянии.
JQuery по-прежнему позволяет писать пользовательский интерфейс, но давайте посмотрим как вы можете написать ту же функциональность используя Vue.
Большинство людей, вероятно, слышали о Vue на данный момент, но для тех кто не знаком с Vue руководство [6] — отличное место чтобы познакомиться.
Сравнение с другими фреймворками [7] также полезно для восприятия Vue в контрасте с другими фреймворками, с которыми вы, возможно, уже знакомы.
Я предлагаю вам установить расширение Vue devtools [8], доступное в Chrome [9] и Firefox [10]. Инструменты разработчика предоставят вам отличную отладочную информацию, когда вы изучаете и разрабатываете приложения с Vue.
Наша версия Vue будет написана с использованием обычного JavaScript, чтобы избежать необходимости беспокоиться об инструментах ES6 и сосредоточиться вместо этого на примере компонента.
Вы увидите как Vue помогает отделять данные от отображения пользовательского интерфейса, с отображением данных в реактивном подходе. Нам также не нужны перемещения по DOM для вычисления значений, которые начинают казаться неуклюжими, когда вы сравниваете как это делается в jQuery по сравнению с React или Vue.
Начиная
Прежде чем писать наш шаблон и JavaScript, давайте обсудим наш подход к построению формы. Думая о данных связанных с формой, я представляю коллекцию (массив) участников и цену одного элемента.
Объект-литерал может выглядеть следующим образом:
var data = {
attendees: [
{ name: 'Example', email: 'user@example.com' }
],
cost: 9.99,
};
Если мы обновим данные, добавив еще одного участника, Vue будет слушать и готов реагировать на это изменение данных:
data.attendees.push({
name: 'Example 2',
email: 'user2@example.com'
});
Имея это в виду, давайте построим приблизительную HTML-разметку и JavaScript скелет для нашего пользовательского интерфейса.
Мы будем постепенно наращивать JavaScript и HTML, чтобы пропустить вас через каждую функцию, которую мы уже рассмотрели в jQuery версии.
Вот начальная HTML разметка для Vue части этого руководства:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue Checkout UI</title>
<linkrel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<style type="text/css">
body {
margin: 3em
}
button {
cursor: pointer;
}
.unit-price {
margin-right: 2rem;
color: #999;
}
</style>
</head>
<body>
<div class="container" id="app">
<form>
<div
class="row justify-content-center"
v-for="(attendee, index) in attendees"
:key="index"
>
<div class="col-sm-3">
<div class="form-group">
<label class="sr-only">Name</label>
<input
class="form-control"
aria-describedby="emailHelp"
placeholder="Enter name"
v-model="attendee.name"
name="attendees[][name]"
required
>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label class="sr-only">Email address</label>
<input
type="email"
class="form-control"
placeholder="Enter email"
v-model="attendee.email"
name="attendees[][email]"
required
>
</div>
</div>
<div class="col-sm-2 text-left">
<button type="button" class="btn btn-light">
<span aria-hidden="true">×</span> Remove</button>
</div>
</div>
<div class="row justify-content-center">
<div class="col-sm-6"></div>
<div class="col-sm-2">
<button type="button" class="btn btn-secondary">Add Attendee</button>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-sm-6">
<span class="unit-price">${{ cost }} ea.</span>
</div>
<div class="col-sm-2 text-left">
<button type="submit" class="btn btn-primary">Pay</button>
</div>
</div>
<form>
</div>
<script src="https://unpkg.com/vue@2.4.4/dist/vue.js"></script>
<script src="app.js"></script>
</body>
</html>
Разметка очень похожа на нашу jQuery версию, но, возможно, вы заметили переменную для цены одного элемента:
<span class="unit-price">${{ cost }} ea.</span>
Vue использует декларативный рендеринг [11] для рендеринга данных в DOM. {{ cost }} — привязка данных с использованием синтаксиса «Усы» и символа доллара $.
Помните объект данных со свойством cost?
var data = {
cost: 9.99
};
Тег усы заменяется значением data.cost при изменении связанных данных.
Затем обратите внимание на строку v-for="(attendee, index) in attendees", которая представляет собой цикл, перебирающий массив данных attendees, и отображающий поля ввода формы для каждого участника.
Атрибут v-for — это директива [12], которая «реактивно применяет к DOM изменения при обновлении значения этого выражения». В нашем примере когда массив data.attendees обновлен, DOM будет обновляться в результате действия этой директивы.
Вы должны начать видеть шаблон: мы модифицируем данные (состояние), и пользовательский интерфейс реагирует на эти изменения. В результате ваш код более декларативный и пишется легче.
В нижней части HTML-разметки у нас есть тег, подключающий скрипт app.js с нашим Vue кодом.
Чтобы инициализировать экземпляр Vue на странице, нам нужно подключить Vue к узлу DOM. Мы предоставили контейнер </ div>, что означает что любая разметка внутри этого элемента DOM будет связана с Vue и реагирует на изменение данных:
(function () {
var app = new Vue({
el: '#app',
data: {
attendees: [{ name: '', email: '' }],
cost: 9.99,
},
});
})();
Мы создаем новый экземпляр Vue, связанный с элементом DOM #app и определяем основной объект данных. Объект данных включает в себя стоимость одного элемента и массив участников. Мы добавили одного пустого участника, так что наша форма по умолчанию будет отображаться с одним набором полей ввода.
Если вы удалите всех участников и сделаете их пустым массивом, вы не увидите никаких имен и сообщений электронной почты.
Все это завернуто в немедленно вызываемое функциональное выражение (IIFE — immediately-invoked function expression), чтобы исключить наш экземпляр из глобальной области.
В jQuery версии мы рассчитали общую цену синхронизируя количество с DOM при помощи события удаления или добавления участника. В Vue, как вы могли догадаться, мы используем data, а затем представление реагирует на эти изменения автоматически.
Мы могли бы сделать что-то вроде следующего, и это будет намного лучше, чем запрос DOM:
<button
type="submit"
class="btn btn-primary"
>
Pay ${{ cost * attendees.length }}
</button>
Тем не менее, слишком много логики в ваших шаблонах делает их менее выразительными и сложными в поддержке. Вместо этого мы можем использовать вычисляемые свойства [13]:
(function () {
var app = new Vue({
el: '#app',
data: {
attendees: [{ name: '', email: '' }],
cost: 9.99,
},
computed: {
quantity: function () {
return this.attendees.length;
},
checkoutTotal: function () {
return this.cost * this.quantity;
}
}
});
})();
Мы определили два вычисляемых свойства. Первое свойство — количество билетов, которое рассчитывается по длине массива attendees.
Второе вычисляемое свойство — checkoutTotal, которое использует первое вычисляемое свойство для умножения количества элементов на стоимость.
Теперь мы можем обновить кнопку проверки используя вычисляемое свойство. Обратите внимание как в результате описано имя вычисленного свойства:
<button
type="submit"
class="btn btn-primary"
>
Pay ${{ checkoutTotal }}
</button>
Если вы обновите свой браузер, вы должны увидеть на кнопке итоговую сумму, вычисленную автоматически.
Когда вы добавляете участника, вычисляемое свойство автоматически обновляется и отображается в DOM.
Мы готовы посмотреть, как мы добавляли бы участников, используя события Vue.
В jQuery мы использовали обработчик событий DOM:
$('.add-attendee').on('click', function () {});
В Vue мы подключаем событие в шаблоне. На мой взгляд это упрощает чтение HTML, потому что у нас есть выразительный способ узнать какие события связаны с данным элементом.
Вы можете использовать v-on:click="addAttendee":
<!-- Using v-on: -->
<button
type="button"
class="btn btn-secondary"
v-on:click="attendees.push({ name: '', email: ''})"
>
Add Attendee
</button>
Или сокращённый вариант click [14]=”addAttendee”:
<!-- Using @click -->
<button
type="button"
class="btn btn-secondary"
@click="attendees.push({ name: '', email: ''})"
>
Add Attendee
</button>
Нормально использовать любой стиль, но хорошая практика придерживаться одного метода. Я предпочитаю сокращённый стиль.
Когда кнопка нажата, мы помещаем новый объект в массив attendees в шаблоне. Я хотел показать вам этот стиль, чтобы вы могли понять, что вы можете просто запустить JavaScript в атрибуте.
В большинстве случаев лучше использовать обработчики событий, потому что, как правило, события имеют более сложную логику, связанную с ними:
<button
type="button"
class="btn btn-secondary"
@click="addAttendee"
>
Add Attendee
</button>
Vue принимает свойства методов в основной объект Vue (и в компоненты), что позволяет нам определить метод обработчика событий:
(function () {
var app = new Vue({
el: '#app',
data: {
attendees: [{ name: '', email: '' }],
cost: 9.99,
},
computed: {
quantity: function () {
return this.attendees.length;
},
checkoutTotal: function () {
return this.cost * this.quantity;
}
},
methods: {
addAttendee: function (event) {
event.preventDefault();
this.attendees.push({
name: '',
email: '',
});
}
}
});
})();
Мы предотвращаем действие по умолчанию и помещаем новый объект на массив attendees. Теперь, если вы добавите участников, вы увидите новые добавленные поля ввода, а checkoutTotal будет соответствовать количеству строк:
Обратите внимание, что обработчик получает объект события, который мы можем использовать для предотвращения действия по умолчанию. Для предотвращения действие события по умолчанию или прекращение распространения (event.stopPropagation()) Vue предоставляет модификаторы событий [15], используемые с точкой (.) как часть атрибута:
<button
type="button"
class="btn btn-secondary"
@click.prevent="addAttendee"
>
Add Attendee
</button>
Ваши методы ориентированы на данные, а Vue автоматически обрабатывает события DOM с помощью модификаторов событий.
Удаление участников похоже на их добавление, но вместо добавления объекта к массиву нам нужно удалить его на основе индекса массива в другом обработчике событий:
<button
type="button"
class="btn btn-light"
@click.prevent="removeAttendee(index)"
>
<span aria-hidden="true">×</span>
Remove
</button>
Мы используем индекс массива чтобы ссылаться на нужного посетителя, которого хотим удалить. Если вы вспомните в нашем цикле v-for, мы определили индекс:
<div
class="row justify-content-center"
v-for="(attendee, index) in attendees"
:key="index"
>
<!-- Attendee inputs -->
</div>
Внутри экземпляра Vue мы определяем метод removeAttendee, который использует splice для удаления одного элемента из массива на основе индекса:
methods: {
removeAttendee: function (index) {
this.attendees.splice(index, 1);
},
// ...
}
С помощью обработчика removeAttendee вы можете добавлять и удалять участников!
Мы также хотим соответствовать бизнес-требованиям c отображением кнопки «Remove» только при добавлении нескольких участников. Мы не хотим разрешать пользователю удалять все входы.
Мы можем сделать это со встроенной условной директивой v-show [16]:
<button
type="button"
class="btn btn-light"
@click.prevent="removeAttendee(index)"
v-show="quantity > 1"
>
<span aria-hidden="true">×</span>
Remove
</button>
Мы использовали вычисляемое свойство quantity чтобы показать кнопку удаления, когда количество больше единицы.
Мы могли бы также спрятать кнопку с условием v-if. Я рекомендую прочитать документацию, чтобы понять нюансы того, как они работают.
В нашем случае мы используем v-show, чтобы показать и скрыть кнопку с помощью CSS. Если вы измените код с использованием v-if и взглянете на DOM, вы увидите что Vue удаляет элемент из DOM.
Вот окончательная Vue версия:
(function () {
var app = new Vue({
el: '#app',
data: {
attendees: [{ name: '', email: '' }],
cost: 9.99,
},
computed: {
quantity: function () {
return this.attendees.length;
},
checkoutTotal: function () {
return this.cost * this.quantity;
}
},
methods: {
removeAttendee: function (index) {
this.attendees.splice(index, 1);
},
addAttendee: function (event) {
event.preventDefault();
this.attendees.push({
name: '',
email: '',
});
}
}
});
})();
Теперь у нас одинаковые функциональные возможности в обеих версиях! Моя цель состояла в том, чтобы проиллюстрировать переход от рабочего процесса на основе DOM к изменению данных и обновлению пользовательского интерфейса в качестве побочного эффекта этих изменений.
Разметка Vue версии более выразительна в передаче функциональности компонента, чем в jQuery версии. Невозможно определить, какие элементы будут обрабатывать события, прикрепленные в jQuery версии. Кроме того, мы не можем предвидеть, как UI будет реагировать на изменение от разметки HTML.
Если у вас еще нет опыта работы с Vue, я рекомендую вам прочитать руководство [6] в конце концов. Как и документация Laravel, руководство читается как книга. В документации вы пройдёте через все, что вам нужно, чтобы начать использовать Vue.
Долгое время приходилось работать с JQuery, но познакомившись с React, а позже и с Vue, решил что надо по возможности начинать их использовать. Vue мне показался довольно простым и понравился синтаксис а увидев эту статью решил поделиться эй с сообществом (ну и заодно попробовать себя в переводах).
Я постарался сохранить стилистику автора, но некоторые предложения чуть переделал для того, чтобы правильнее передать смысл.
Сильно не ругайте — это мой первый перевод.
Автор: Алексей Родионов
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/267652
Ссылки в тексте:
[1] Vue.js Tutorial: From jQuery to Vue.js: https://laravel-news.com/jquery-vue
[2] Paul Redmond: https://laravel-news.com/@paulredmond
[3] с использованием jQuery: https://codepen.io/paulredmond/pen/KXegwb
[4] с использованием Vue: https://codepen.io/paulredmond/pen/XeYKLv
[5] литерал: https://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D1%82%D0%B5%D1%80%D0%B0%D0%BB_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
[6] руководство: https://ru.vuejs.org/v2/guide/index.html
[7] Сравнение с другими фреймворками: https://ru.vuejs.org/v2/guide/comparison.html
[8] Vue devtools: https://github.com/vuejs/vue-devtools
[9] Chrome: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
[10] Firefox: https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/
[11] декларативный рендеринг: https://ru.vuejs.org/v2/guide/index.html#Декларативный-рендеринг
[12] директива: https://ru.vuejs.org/v2/guide/syntax.html#Директивы
[13] вычисляемые свойства: https://ru.vuejs.org/v2/guide/computed.html
[14] click: https://habrahabr.ru/users/click/
[15] модификаторы событий: https://ru.vuejs.org/v2/guide/events.html#Модификаторы-событий
[16] встроенной условной директивой v-show: https://ru.vuejs.org/v2/guide/conditional.html#v-show
[17] Источник: https://habrahabr.ru/post/341798/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.