5 ms·
My current preference in Vue 3 (with the Composition API) but using JSX (which is generally only mentioned with React) instead of Vue HTML templates (e.g. https
by seanwilson 2y ago
My current preference in Vue 3 (with the Composition API) but using JSX (which is generally only mentioned with React) instead of Vue HTML templates (e.g. https://vuejs.org/guide/extras/render-function#v-for https://vuejs.org/guide/extras/render-function#v-for, https://vuejs.org/guide/extras/render-function.html#jsx-tsx https://vuejs.org/guide/extras/render-function.html#jsx-tsx) with TypeScript. Correct me if I'm out-of-date, but my understanding is Vue is more batteries included, and state management is more concise. I strongly prefer JSX :
- I can write for-loops, conditions, etc. in the same language I write my logic in with the same TypeScript and (Vscode) IDE support (e.g. refactoring, formatting, error reporting) vs using a special template language + IDE plugin.
- I find HTML templates really ugly and harder to read in that your dynamic logic code gets lost inside the static markup and presentation code e.g. `<li v-if="items.length > 2" v-for="{ id, text } in items" :key="id" class="card card-body fw-bold small"> {{ text }} </li>` vs `{items.length > 2 && items.map(({ id, text }) => (<li key={id} class="card card-body fw-bold small">{text}</li>))}` (still quite ugly but most of the logic is on the outside now).
- I can easily assign chunks of HTML to variables or generate HTML snippets via concise functions in regular TypeScript instead of being forced to create a new verbose component via HTML templates each time e.g. the arrow function above can be assigned to variable and reused. HTML templates feel very limiting in comparison.
It's sometimes awkward finding the JSX syntax (like for using Vue slots), but this is more because it's less common.
Would be curious of others who have tried this Vue 3 + JSX combination!
- apatheticonion 2y agoAwesome! How do you use Vue with tsx/jsx?
- zwnow 2y agoWhen you set up a project it asks you if you want to use jsx afaik
- seanwilson 2y agoThis documentation is pretty good for this, it's a supported option rather than something you have to hack in but I rarely hear it mentioned: https://vuejs.org/guide/extras/render-function.html#jsx-tsx https://vuejs.org/guide/extras/render-function.html#jsx-tsx Edit: Yes, oops, wrong link.
- mcintyre1994 2y agoI think that link should be: https://vuejs.org/guide/extras/render-function.html#jsx-tsx https://vuejs.org/guide/extras/render-function.html#jsx-tsx
- apatheticonion 2y agoOh right, sorry I thought that was docs for the original vue-templates. Should have checked. Do you happen to know if I can I use my own bundler set up with this? (esbuild, rspack, etc?)
- stevage 2y agoI prefer Pug with Vue3. Your example would be: ``` li.card.card-body.fw-bold.small(v-if="items.length > 2" v-for="{ id, text } in items" :key="id") | {{ text }} ``` Personally I find this really readable. The HTML element is the most visible thing, then we get classes, then all the logic in parentheses. Then, standing by itself, the content. And we don't need any closing tag.
- luminarious 2y agoPug templates have been the most readable in my projects. Underappreciated imho, wish Astro also supported it.
- psychoslave 2y agoAgree, but isn't the project very low in activity? https://github.com/pugjs/pug/activity https://github.com/pugjs/pug/activity That is not necessarily a bad thing, sometime stability is what matters the most. But here the last commit was removal of a security and bugs branch...
- antifa 2y agoPug has been pretty complete for quite a while, there just isn't that big of a potential for insecurity for something that becomes vue's html/jsx at build time and 99% of run time threats is basically that the dev sent unsanitized use input to v-html instead of v-text. The main problem with pug is that, AFAIK, vue is the only modern webframework with stable support for it.
- deleted 2y ago[deleted]
- seanwilson 2y agoYeah, regular HTML is overly verbose. Being able to compose JSX generating functions and using regular JavaScript logic for loops, conditions etc. wins out for me though because realistic HTML gets big and messy otherwise. Can you do something like this in Pug? (where the actual HTML would be more complex, so you'd want to split it up like this) const elToolbar = generateToolbar(toolbarItems) // returns JSX const elUserCards = users.map(user => <div class="card card-body fw-bold">{{ user.name }}</div>) return <div> {elToolbar} {elUserCards} </div> I find doing something similar with Vue HTML templates has far too much boilerplate, and I have to learn/recall all this Vue specific boilerplate instead of using regular functions so I end up not breaking up my HTML as much. Unless there's a way to do something similar within in a single file?
- uallo 2y agoThe one thing that bugs me tremendously with Vue template syntax is slots. They are so annoying to use and hardly visible in code completion. Passing template/HTML fragments as props is so much nicer in JSX. This is the only reason, why I even consider using JSX instead of Vue's template syntax. Thus, I'm very much interested in your experiences with Vue+JSX. Especially in regards of (third-party) tooling support. While JSX is officially supported by Vue, it does not seem to be encouraged and may have subpar support in the ecosystem. But that is only something I'm afraid of, I do not have any experience with it, yet.
- seanwilson 2y ago> Passing template/HTML fragments as props is so much nicer in JSX. Ha, I do this in places but I'm not sure if this approach is encouraged? Compared to slots, I like this too, it's a lot less verbose and the syntax is simple and easy to remember. > While JSX is officially supported by Vue, it does not seem to be encouraged and may have subpar support in the ecosystem. But that is only something I'm afraid of, I do not have any experience with it, yet. Worst case, you can switch to Vue HTML templates in some files and use JSX in others. I've not found issues mixing them together like this.
- yurishimo 2y agoDoes this also allow you to write multiple components in one file? I guess there wouldn’t be a problem with it if you use the primitive inside of a normal JS file. I’ve seen the third party package for the compiler that has popped up to try and handle this, but I don’t like the limitations. I’m hoping with Vue 4 they will find a way to support multiple components in one SFC file (which kinda violates the naming but hey…)
- seanwilson 2y ago> Does this also allow you to write multiple components in one file? I guess there wouldn’t be a problem with it if you use the primitive inside of a normal JS file. Yes, as in a component would be a regular JavaScript function that takes some parameters and gives you back some JSX to render. It's really concise and there's no need to muck around with plugins or anything special, it's just regular JavaScript. When I'm working on projects that use Vue HTML templates, I've often got pages that have some small HTML snippet that appears two or three times, and just don't want to go through the effort of having to break the snippet out into its own component file because its so verbose. JSX makes this really low friction so you do it more often.
- crabmusket 2y agoI have only tried your approach on small side projects. I quite liked it, for the reasons you mention. And for one more reason: the only tooling needed is esbuild, which can handle TSX. No finding a Vue SFC plugin, just a single dependency and you're off. (Of course you'll probably also want to install typescript itself as IDE type checking isn't adequate for a real project.)
- seanwilson 2y agoYeah, I like that JSX is built into TypeScript like this so it's more standardised with less tooling required. JSX is probably less likely to change given its relatively wide usage compared to each framework having it's own template language and JSX is well supported by linters and formatters too.
- rk06 2y agoPersonally i prefer to put v-for/v-if/else in a separate <template> tag. It makes it easier to identify and makes order explicit
- deleted 2y ago[deleted]