That is a general theme, I've found - compared to React, Vue makes the easy things easier, but the hard things harder.
That is a general theme, I've found - compared to React, Vue makes the easy things easier, but the hard things harder.
You use a dynamic component:
<component :is="condition ? 'WrappedComponent' : 'UnwrappedComponent"></component>
> That is a general theme, I've found - compared to React, Vue makes the easy things easier, but the hard things harder.While react make the easy things annoying. It took me an afternoon to be productive with vue, several weeks with react.
And all that for what?
Having the privilege to "just use javascript"? Here is "just javascript" in jsx:
{items.map((items) => (
{display && <SomeElement
onClick={e => e.preventDefault() && foo()}
className="`${active ? 'current' : ''}`" />}
))}
Here is the same in vue template: <SomeElement
v-for="item in items"
v-if="display"
@click.prevent="foo()"
:class="{'current': active}" />
Not only the react blob is impossible to scan, but it will be different depending of the dev who coded it, because there is no enforced patterns. You must use brain power to parse every single template line. HTML, that thing that was simple and declarative, now becomes complicated and imperative.And that's not even weird or unusual code. That's regular stuff one writes all the time. Don't get me started on state management or spaghetti hooks.
I have yet to work on a react code base I was more productive than on a vue one. And the gaps get wider if the team is not composed of excellent coders, because react code by junior is a nightmare.
Admittedly due to the nature of Vue syntax, it's harder to make a mess because everything is just key/value.. but then you have to learn an API to express things in that way. I enjoy the fact that you don't have that layer/step with react.
I definitely feel that the 3rd party classnames package should be built into React, I agree that out of the box conditional class names look a mess.
I don't have enough experience with either library yet to form an opinion on which I prefer, but I definitely appreciate not having the mental overhead of remembering the vue api. I'd rather have a bit of code that's more explicit/"just javascript" than have to think "what's that symbol I need to use again?". Definitely a personal preference thing though!
{items.map((item) =>
item.display && (
<SomeElement
onClick={(e) => e.preventDefault() && foo()}
className={classNames({'current': item.active})}
/>
)
)}And in the end, I still have to read 2 JS expressions before even figure out what DOM element I'm actually dealing with. Then I still have to evaluate what the heck is happening in onClick and className.
I still have to parse code in my presentational layer, code that is interleaved with my template indentation so it also makes it hard to understand hierarchy and easy to make mistakes.
Of course, the elephant in the room we are not talking about with react is that all those things compounds. When you have 5 of such blobs in your render functions, issues don't add up, they multiply.
Then you add the store system on top of it, with actions, reducers and all that fun stuff.
It's not really that big of a deal to have another import. Vue's directive's (not sure if that's the correct term) are a mix bag of magic strings that tie to functions somehow. Why can't they just be a function variable like in React? The answer of course is there are smart people and smart users behind both projects and those are the trade-offs we tolerate.
But even so, Vuex way better integrated, requires less boilerplate (thanks vue reactivity) than redux, or even zustand, which once you add immer, looks like blobbing all over again.
Honestly, we should do a contest. Take 10 juniors out of school give them a twitter clone to write, 5 in Vue, 5 in React, and come back in a week.
In fact, no need for them to be junior. Let's just take your regular Java dev. Not your 10X HN dev. Just average Joe. See how it goes.
1) Build a clone of a site or implement a design with their tool-of-choice (basic competency). For the ones who opt to start without frameworks, we also get a glimpse at how good their organization skills are.
2) After they are done, we give them several "requirement changes" and see how well/fast they adapt. People can trumpet whatever best practices they believe, but this is the part of the interview where some best practices are more practical than others.
3) Modify an existing project. Here, we pick the opposite of their preferred stack/methods. ie, if they prefer vue, we give them a react or svelte app to modify. If they prefer BEM, we give them functional (we use tailwind); if they prefer utility-first, we give them BEM or smacss, etc. While it may seem on-the-spot, it gives us an insight to how well they work outside their comfort zones and adapt to unfamiliar techs.
Our in-house developers are pragmatists over purists, while still being specialists in various techs. And we're fluid with our tech/tools and everyone is at least an expert in one of the current web techs.
And the best thing (imo) about my team is, everyone is excited about new tech. We always try to one-up each other in our various specializations, hence, are also aware of the limitations of our area-of-expertise.
Which comes in handy during interviews. If a candidate says they are an expert in css, we have a resident css expert that can put their claims to the test. You wouldn't believe how many failed candidates proclaim to be a css purist, only to fall short when it comes to organizing and scaling and documentation.
The whole ecosystem of state management does feel like a bit of a wild west.. but I guess that's often the feeling with javascript.
I ended up settling with easy-peasy, which I think has similar aims to zustand. Definitely appreciate that it uses immer out of the box as that seems like a very sensible default way to go.
That requires you to create 2 new components (which unlike React, will need to be in separate files if you're using SFCs) and pass down all the props another layer.
In the end, I got around it by implementing a "passthrough" component so that you can then do
<component :is="condition ? 'Wrapper' : 'passthrough'>...</component>
but that is far from ideal.> Not only the react blob is impossible to scan
Formatted properly, I don't really find the React example any harder to read.
Your Vue example puts v-for and v-if on the same element, which is confusing - which is evaluated first? (IIRC, the answer depends on which version of Vue you are using).
> it will be different depending of the dev who coded it, because there is no enforced patterns
That applies to the rest of your codebase too, though. It's up to your team to decide on patterns and enforce them through linting, code review, and automatic formatting.
Also, both of your examples are missing `key`, though React will warn you about it and Vue will not.
Vue will warn when you're missing a key on the loop.
>That requires you to create 2 new components (which unlike React, will need to be in separate files if you're using SFCs)
Your components don't need to be in separate files even when using SFC's. Given 'component' can be as simple as adding to any Vue Component or SFC (when adding it to parent component option):
<script>
const myComponent = {
props: ['myProps'],
template: `
<div></div>
`
}
</script> import cn from 'classnames'
const prevent = fn => e => e.preventDefault() && fn()
// don't forget key
{items.map(item =>
display && <SomeElement key="" onClick={prevent(foo)} className={cn(current: active)} />
)}And now you have to install and manage deps, import them, while your blob is still less readable because you have maps+lambda+&& to understand before even reaching what DOM element you are manipulating.
The premise of React is that composing primitives is better than having a high level tool to do the job: it's supposed to be more generic, more flexible, easier to learn.
In in my experience, it's true only in the case you don't have a well defined problem. But with frontend UI, we do. We know very well the problem to solve. Give me helpers. Give me wrappers. That's the only case where I welcome a DSL.
I don't want to have to think in functions and workflow in my template.
`onClick={prevent(() => newLambda(what, ever)}}`
I'd say Vue is the much more powerful tool in the hands of a skilled developer
JS itself is a single-threaded event loop and all view engines basically follow the same functional pattern of data-> render function -> output. Vue comes with an HTML parser to create that render function, React and others use a JSX parser, or you can write your own from raw javascript.
You can technically use any of them with any render function parser, but Vue starting with HTML by default and all the other niceties around reactivity make it a better fit.
If you wanted to get fancy, you could also accept a tag prop and v-bind all other $attrs on the container to make that a general purpose component.