3 ms·
No, Vue's templates do not allow arbitrary JS. The syntax is very Angular-like, in the sense that everything is pseudo-html using custom tags and attributes. Bu
by vec 9y ago
No, Vue's templates do not allow arbitrary JS. The syntax is very Angular-like, in the sense that everything is pseudo-html using custom tags and attributes. But the builtins are extremely well thought out and in practice I rarely find myself having to re-implement much of anything that's not application specific, and most of those things I'm grateful to implement once and be done with it instead of having to reimplement in JS for every component that needs it.
There is more of a learning curve, in the sense that it only took me 1-2 hours to feel like I fully understood JSX and maybe a day and a half to feel like I fully understood Vue templates. I, personally, don't find that argument very compelling. ~10 dev hours is a rounding error over the lifetime of a project, and anyway I spent at least that much time researching and/or reinventing JSX conventions and idioms that are obvious or trivial in any real templating DSL. I only had to climb the conceptual hill once for each framework, and the view from the top is much nicer in Vue.
As an aside, Vue actually supports JSX out of the box. Any component can optionally include a `render` function that's almost exactly like React's `render`, and it falls back to using Vue templates only if no `render` is specified. Anecdotally, though, there is only a single component in our entire application where the team decided it was cleaner in JSX than with a template.
- ianstormtaylor 9y agoThe learning curve is only one place the choice ends up being worse. (Just read the Vue docs to understand.) The other is that you now have "directives" that are defined elsewhere, in other files, that are included into templates via strings, instead of anything that is easily statically (or quickly) analyzable. Some of these directives ship with core, but some are third-party, so you have to remember which is which, and which your team has added. But that's not it, those "directives" can have "modifiers" that can augment the already blackbox directives however they want. Not only that, but it seems that bindings can actually execute arbitrary Javascript as expressions. Which is great, except apparently you can do that in strings too, so you end up writing code like: <div v-bind:id="'list-' + id"></div> Now you're basically writing JSX, you're just doing it all inside of strings that are hard to lint, analyze, etc in the HTML attributes of your templates instead. It all adds up to lots of redirection and re-inventing the wheel, when you could just be using Javascript itself. (Although I'm sure there's _way_ less redirection than Angular.)
- vec 9y ago> Some of these directives ship with core, but some are third-party, so you have to remember which is which, and which your team has added. Not to nitpick, but I think this might be the nut of our different reaction here. Some of our directive are core, and some are third-party. 99% of the time I don't have to know or care which is which. I just use them and they work and I don't have to think about how or why. Perhaps this would be clearer with an example. Our API serves numerous types of copy as markdown strings. In our React code, embedding a markdown string (assumed to be in `this.state.copy`) into a div looked like this: <div dangerouslySetInnerHTML={{__html: md(this.state.copy)}} /> In Vue, it looks like this: <div v-md="copy" /> The first one is easier to statically analyze, but the second one is far easier for humans to read and to write. Vue allows me to abstract away all the details of how `copy` gets turned into HTML so that my templates can clearly express what I want them to do. The signal to noise ratio remains high, and if it starts to feel verbose or boilerplatey I have a large box of tools with which to fix it.
- chenglou 9y agoStatic analysis aside, the first snippet using the React API is very much designed to be used sparingly. I feel It's a bit of an unfair comparison to take an escape hatch that's intentionally verbose and indicative of "dangerously using strings directly" and judge it based on its convenience... Maybe you're hitting a pathological use-case because of the nature of your API. In which case you can always wrap it inside a single function and just do `<MyMarkdown text={bla} />`
- vec 9y agoI did choose a pathological case, partly because there's no way to write the `md` helper function in a way that react will just treat as always safe, other than wrapping it a component. But then components requires a single root element and unless I want it to always be a div I also have to pass in a tag name and this is rapidly ceasing to feel simple. But it's not just contrived examples. Here's a list: <ul> {(this.state.items || []).map(item => ( <li>{item}</li> ))} </ul> vs <ul> <li v-for="item in items">{item}</li> </ul> And here's a simple if/else let loginOrLogout if (this.isLoggedIn()) { loginOrLogout = <LogoutButton /> } else { loginOrLogout = <LoginForm /> } // snip <div>{loginOrLogout}</div> vs <div> <logout-button v-if="isLoggedIn" /> <login-form v-else /> </div> React is conceptually simple, but that often forces me to write complex code. Vue lets me keep the code I write (i.e. the only code I actually care about) simple.