Оригинальная заметка Матиаса Питера Йохансона, переведена с разрешения автора.
Меня часто спрашивают, что я думаю о Vue.
Не буду оценивать Vue, так как я недостаточно хорошо знаком с ней, но я очень хорошо знаком с шаблонизаторами. Собственная система шаблонов Vue вместо JSX во многих статьях преподносится как причина, по которой вы должны выбрать Vue. Из-за этого я на стену лезу от негодования, потому что негативные стороны этого подхода даже не удостаиваются упоминания или обсуждения. JSX существует по достаточно веским причинам. Для меня JSX — большой шаг к упрощению и улучшению шаблонов.
Языки шаблонов часто продаются за счёт поверхностной элегантности. Недавно я наткнулся на очередную статью, восхваляющую Vue (и особенно её шаблоны). В ней был следующий пример JSX:
render() {
let { items } = this.props
let children
if (items.length > 0) {
children = (
<ul>
{items.map(item =>
<li key={item.id}>{item.name}</li>)}
</ul>
)
} else {
children = <p>No items found.</p>
}
return (
<div className="list-container">
{children}
</div>
)
}
В статье этот пример осуждается за многословность, а затем приводится его реализация на Vue:
<template>
<div class="list-container">
<ul v-if="items.length">
<li v-for="item in items">
{{item.name}}
</li>
</ul>
<p v-else>No items found.</p>
</div>
</template>
Это выглядит как лукавство со стороны автора, потому что первый пример действительно написан слишком многословно. В более лаконичном виде он выглядел бы так:
let ListContainer = ({ items }) => {
<div className="list-container">
{items.length === 0
? <p>No items found</p>
: <ul>
{items.map(item =>
<li key={item.id}>{item.name}</li>
)}
</ul>
}
</div>
}
Я не знаю, специально ли автор вводит читателей в заблуждение, или он просто взял пример из какого-то руководства по React. Буду считать, что он взял пример из какой-то статьи. Если это действительно так, есть вероятность, что пример JSX был специально написан многословно для большей наглядности и очевидности происходящего: при изучении новых инструментов вам не нужна краткость, вам нужно простое и понятное объяснение того, как инструмент работает, без лишней магии.
Пример с Vue, однако, не особо даёт понять, КАК на самом деле он, чёрт возьми, РАБОТАЕТ. Я знаю, как работает Array.map
, но что такое v-for
и что за синтаксис используется внутри этого атрибута? Да, довольно легко понять ЧТО конкретно этот шаблон делает, потому что он читается почти как обычная речь на английском. Но когда вы на практике столкнётесь с подобными языками шаблонов, ваша продуктивность ощутимо упадёт, потому что вам придётся тратить время на изучение (и часто расширение) языка. Да, это небольшой язык, но это всё ещё язык, который придётся изучить. В случае с JSX вещей для изучения гораздо меньше, и в нём можно применять уже существующие знания и инструменты JavaScript.
Предположим для примера, что я хочу отфильтровать все элементы, которые неактивны. JSX — это просто JavaScript, поэтому я спокойно использую filter
:
let ListContainer = ({ items }) => {
<div className="list-container">
{items.length === 0
? <p>No items found</p>
: <ul>
{items
.filter(item => item.active) // <-- ДОБАВЛЕННАЯ СТРОКА
.map(item =>
<li key={item.id}>{item.name}</li>
)
}
</ul>
}
</div>
}
Как это сделать в шаблоне Vue? Честно, без понятия. Я хотел привести здесь пример, но спустя десять минут гуглинга я всё ещё не мог найти, как это делается. Конечно, можно найти, как это делается, но суть в том, что у меня УЖЕ ЕСТЬ Array.filter
! И проблема возникла ТОЛЬКО из-за того, что мы изобрели новый язык вместо использования уже существующего.
PHP-сообщество поняло это 10 лет назад, когда большинство вменяемых PHP-программистов перестали использовать Smarty, поняв, что PHP — сам по себе замечательный язык шаблонов.
Нет никакой разницы и в случае с JavaScript — он замечательно подходит на роль языка шаблонов, так что не изобретайте ещё один узкоспециализированный язык.