JSX is closer to JS than HTML, which means it annoying to write in some cases. Quick, what does this render as?
<a href="...">Link 1</a> |
<a href="...">Link 2</a> |
<a href="...">Link 3</a>
It's not Link 1 | Link 2 | Link 3
as you'd expect - instead, the whitespace after the pipe character is eaten by JSX. This is because HTML is whitespace sensitive, but JS is not, and so to allow indentation, JSX trims whitespace.Here's another -
<dl>
{ Object.entries(definitions).map(([term, definition]) => (
<dt>{ term }</dt>
<dd>{ definition }</dd>
)}
</dl>
This does not work - instead, you need to return an array, but the result is ugly - the commas are part of JS, not HTML, and don't appear in the output, but reading this quickly it's hard to see that (the difference is the braces surrounding the block). <dl>
{ Object.entries(definitions).map(([term, definition]) => ([
<dt>{ term }</dt>,
<dd>{ definition }</dd>,
])}
</dl>
Vue's 'weird DSL' is HTML (the same is not quite true for Angular's). What you see is exactly what you get. Having a DSL also means you can define your own syntax. Things that are verbose (due to historical reasons in JS), such as iterating over an object, can be made simple - <dl>
<template v-for="(definition, term) in definitions">
<dt>{{ term }}</dt>
<dd>{{ definition }}</dd>
</template>
</dl>