Vue.js 2 представил свою собственную реализацию Virtual DOM. На первый взгляд, кажется что это никак не отразится на том как вы пишите шаблоны. Из документации:
Под капотом, Vue компилирует шаблоны в render-функции для Virtual DOM. В совокупности с системой реактивности, Vue способен грамотно определять минимальное количество компонентов для повторной визуализации и выполнять минимальное количество действий с DOM при изменении состояния приложения.
Virtual DOM освобождает от довольно большой части оптимизации: теперь вы можете предварительно скомпилировать шаблоны в чистый JavaScript, таким образом Vue.js может не делать этого в браузере.
Без предварительной компиляции шаблонов в процессе сборки, Vue.js будет переводить строковый шаблон в JavaScript render-функцию, во время выполнения. Это означает, что на этапе начального рендеринга потребуется больше времени, по двум причинам: ваш уже собранный скрипт должен включать в себя Vue компилятор (больше время для загрузки) и шаблон должен быть скомпилирован, перед тем как он будет использован (больше время выполнение).
Эта статья не о синтаксисе шаблонов в Vue.js 2, а о том где и как определять ваши шаблоны. Я написал её, потому что на текущий момент не нашёл ни одного ресурса, который бы на самом деле объединил различные способы управления вашими шаблонами.
Я разделил различные способы определения шаблонов на 3 разные категории, у каждой из которых есть собственные преимущества и недостатки:
- Написание шаблонов, которые компилируются во время выполнения (наименьшая производительность);
- Использование отдельного .vue файла для компонентов (требуется этап сборки);
- Ручное написание render-функций (чистый JavaScript, не HTML-подобный синтаксис);
Использование не скомпилированных шаблонов
Шаблоны в Vue.js необязательно должны быть скомпилированы. Если вы используете runtime версию Vue.js, то шаблоны могут быть скомпилированы прямо в браузере. Это решение отличается простотой. Никаких лишних этапов сборки или специальных типов файлов, но такой подход жертвует производительностью. Первый рендеринг компонента займёт больше времени, потому что шаблон сначала необходимо скомпилировать в JavaScript.
Определение шаблонов в компоненте
Самый простой способ определить шаблон компонента - это определить его в параметре template.
// greeter.js
Vue.component('greeter', {
template: '<div> Hello, {{ name }}!</div>',
props: ['name'],
});
В JavaScript, строковый тип данных не может быть размещён на нескольких строках кода. Если вы хотите чтобы ваш выглядел свободно, можете использовать шаблонные литералы.
// greeter.js
Vue.component('greeter', {
template: `
<div>
Hello, {{ name }}!
</div>
`,
props: ['name'],
});
Кроме того, если вы используете такие сборщики как Webpack или Browserify, вы можете определить шаблон в отдельном файле. Параметр template может принимать значение require.
// greeter.js
Vue.component('greeter', {
template: require('./greeter.html'),
props: ['name'],
});
// greeter.html.js
module.exports = `
<div>Hello, {{ name }}!</div>
`;
Определение шаблонов в атрибуте type="x-template" тега script
Тег script с атрибутом x-template может содержать шаблон, к которому компонент будет обращаться по ID.
// greeter.js
Vue.component('greeter', {
template: '#greeter',
props: ['name'],
});
<!-- index.html -->
<script type="text/x-template" id="greeter">
<div>Hello, {{ name }}!</div>
</script>
На самом деле, это решение не очень, так как оно создаёт довольно большой разрыв между вашими шаблонами и компонентами, а по факту не приносит никакой пользы (даже официальная документация отговаривает нас от использования x-template).
Использование inline-template атрибута
С помощью специального атрибута inline-template, шаблон может быть указан во внутреннем содержании компонента.
// index.js
Vue.component('greeter', {
props: ['name'],
});
new Vue({
el: '#app',
});
<!-- index.html -->
<div id="#app">
<greeter inline-template>
Hello, {{ name }}!
</greeter>
</div>
Это может оказаться полезным, если вы хотите чтобы HTML был виден сразу после того как он пришёл с сервера. Однако, как правило использовать встроенные шаблоны не рекомендуется, потому что такой подход делает его сложнее для обдумывания масштабов вашего компонента.
Использование отдельного файла компонента (.vue файлов)
Отдельный файл компонента существовал уже в первой версии Vue.js. В Vue.js 2 он приносит больше пользы: шаблоны будут предварительно скомпилированы в чистый JavaScript.
Vue файлы позволяют вам определять шаблон и скрипт в отдельном файле, который будет скомпилирован в JavaScript с помощью Webpack или Browserify.
<!-- Greeter.vue -->
<template>
<div>Hello, {{ name }}!</div>
</template>
<script>
export default {
props: ['name'],
};
</script>
Отдельные файлы компонента также открывают дверь более интересным возможностям, таким как написание шаблонов с помощью HTML или CSS препроцессоров. Это означает, что вы можете писать шаблоны например с помощью Pug (формально Jade).
<!-- Greeter.vue -->
<template lang="pug">
div Hello, {{ name }}!
</template>
<script>
export default {
props: ['name'],
};
</script>
<style lang="sass" scoped>
div {
text-decoration: blink;
}
</style>
Обратите внимание на то, что поскольку вы используете специальный тип файла, становиться труднее добавлять другие инструменты в ваш проект. Например, если вы хотите писать тесты или анализаторы (lint'ы) для ваших компонентов, то сначала их нужно скомпилировать, а также у редакторов кода могут возникнуть проблемы с .vue файлами.
Использование render-функций
Написание сырых render-функций
Когда используются различные стратегии шаблонизации (компиляция во время выполнения или отдельные файлы компонентов), строковые шаблоны компилируются в render-функции автоматически.
Написание ваших собственных render-функций даёт вам максимальную производительность без стадии сборки, но дело в том, что они не HTML-подобные и с ними труднее работать.
// greeter.jsx
Vue.component('greeter', {
render(h) {
return h('div', `Hello, ${this.name}!`);
},
props: ['name'],
});
Написание render-функций с помощью JSX
render-функции могут быть написаны в JSX формате с помощью плагина Babel, что позволяет достичь более HTML-подобного синтаксиса.
// greeter.jsx
Vue.component('greeter', {
render(h) {
return (
<div>
Hello, {{ name }}!
</div>
);
},
props: ['name'],
});
Обратите внимание на то, что большинство встроенных во Vue.js 2 директив не будут доступны при использовании JSX, но обычно у них есть собственные программные эквиваленты (например, вы можете заменить v-if на обычный if из JavaScript).
Вывод
Если вы разрабатываете большое приложение, в котором производительность является очень важным фактором (обычно SPA) или заинтересованы в использовании препроцессоров, то кажется вам подойдут отдельные файлы для Vue компонентов.
Если вы не против первоначальной потери производительности и готовы использовать компиляцию во время выполнения (случаи, которые просто улучшают страницу), я рекомендую использовать литералы JavaScript шаблонов в параметре template компонента. Это не привнесёт никаких чуждых концепций в ваш процесс сборки и сохранит ваш шаблон вместе с компонентом.
Комментарии
Хотелось бы следить за новыми постами где-нибудь во ВКонтакте или телеграме.
Единственный вариант на данный момент, это RSS https://wp.tuhub.ru/feed
Нет , пилить до уровня Angular2 будут еще долго , если даже такие базовые вещи как динамическая загрузка и компиляция шаблонов лежат за рамками фреймворка. И это только первый поверхностный взгляд , а если попробовать применить в серьезных проектах ? - придется еще 100500 библиотек юзать.