Fortunately it doesn't regress from what we have learned before either.
The most important factor in favor of Vue however, is that it 'just works'. When working in the reaction ecosystem I feel like I'm constantly trying to couple together chains that call functions on functions on objects.
Then there's the components that have bugs that make them fail in the most basic of situations.
And lastly I have to write 3 times as much code to get all of it even running.
Give me Vue and it's magic any time of the day.
When working in the [react] ecosystem I feel like I'm
constantly trying to couple together chains that call
functions on functions on objects.
This is a very good explanation of how I feel as well. At work I use React, but on sideprojects I'm a Vue fan. React feels like layers and layers of render functions, with chains passed down and pared down as you get deeper, which becomes excessively cumbersome to reason about. Vue feels like it compartmentalizes things much more effectively. A component can just be a component, not a stateless function that renders a react component that wraps around a redux plugin component, with each step having its own little isolated DSL.This reads more like a design problem than with React. React gives you the component and some good practices and advices in the documentation, but how you compose them is in the end your responsibility.
> Vue feels like it compartmentalizes things much more effectively. A component can just be a component, not a stateless function that renders a react component that wraps around a redux plugin component, with each step having its own little isolated DSL.
I think it's unfair using DSL here. Even Redux makes a big point out of not creating too many conventions nor sugaring, and people actually complain about the boilerplate. Redux's `connect` is a function that does no magic: returns a function that will return you a component (which like you point out could even just be another function) with props mapped as per your initial arguments. No DLS, no magic.
That a component can be just a component, not a stateless function to me doesn't make much sense, given how functions are primitive constructs and components are not. I think the fact that components can be just stateless functions is good because it means composing components is no different from composing functions.
And again, if a stateless component renders another component and wraps a redux connected component it either makes sense based on what the developers are trying to achieve or maybe they are just over-complicating things, but React wouldn't be responsible for either decision.
This is like saying recursion is hard to reason about because you're dealing with a function which calls itself then calls itself then calls itself and there are layers and layers of calling itself with chains of arguments passed down through the many layers.
> a stateless function that renders a react component that wraps around a redux plugin component
IMO React's recursion makes it much easier to reason about than something imperative like Vue, while its function composition enable powerful patterns for reusing logic.
There are actually a lot of similarities with React.
Neither are useless nor bad per se, but given options, in majority of cases both are more of a smartass thing to do rather than the most optimal or most maintainable / developer friendly thing to do.
Regarding recursion, I find that recursion is easier to understand than an equivalent while-loop, but maybe it's personal preference. Also, most people shouldn't have to worry about optimizations like tail recursion.
> when someone else needs to read such code, it's hard for them to reason about it.
I'll admit, there are a few negatives with React, but they don't outweigh the positives. Micro-optimizations in user-land should never be seen by designers and if they are, then something is wrong. React's diffing algorithm is a leaky abstraction and forces the designer to be aware of component optimization, since how you break up your components affects how much work the diff has to do.
The new context API is inelegant and it feels like a square peg in a round hole. Additionally, shouldComponentUpdate is the wrong abstraction -- it is very imperative and it pushes you to break your components down into smaller components even if your app's organization suffers.
Reusability and organization should be the only two reasons for creating new components -- performance shouldn't be a plausible reason, because it creates a higher degree of overlap between the developer and the designer.
I understand why people feel overwhelmed with the whole React/Redux/Router/Saga stack but you really don't need most of that when you're just getting started and React itself is quite simple and elegant.
They are supremely useful. Ultimately, it's knowing how to use them to their maximum potential.
I've been coding since '02-ish. When I code with Vue, I have an App Developer mindset, rather than a web developer jQuery mindset.
When I use an attribute, it's just referencing a variable. It reacts to its own state in real-time.
I'm not the best at explaining. But with a legacy mindset, you have to interact with the DOM in some way. Whereas with HTML attributes in Vue, you can use the state in the local component to determine whether something is shown or even if a particular class is shown depending on what the state is of a variable.
Even better, that could be a computed variable or one that's watched. This functionality allows a bit of logic to then be run to determine how that variable behaves. This alone minimises the code I need to write in terms of legacy applications. Which also leads to less bugs.
Using if, for, show, and binding classes are very very powerful. I rarely interact with the DOM now and everything in state that is complex is an array. I can write way more complex apps with Vue, than I ever could with jQuery.
About the examples given here by the developer. You can still see that he's coding with a legacy mindset and that he hasn't internalised a lot of what Vue offers.
Some minor nitpicks:
- No need for this.$parent.$emit. There is a better way to use $emit.
- this.$on. <- What is this? An Event Bus? This should really have been a method.
- No need to use id attributes at all.
- Why not pass in the index attribute (which he is not using) to the delete function and then he can simply splice the array?
If he wanted to be real flash. He could have written the ToDo component as a JSX render function and taken the array from the parent and looped out the list. I know the Vue community looks down on it, but would have been a better way of going.
I don't really want to seem like I'm crapping over this. I'm not. I've only been using Vue since April myself. But there seems to be a lot of mistakes here and it's just not idiomatic.
As an aside, I thought I'd let you know that I've been a developer for just under one year, so admittedly do not have anywhere near the level of expertise that you have. I've also only been using Vue since April, but I guess that my level of overall experience, relative to yours, is lacking somewhat.
I got ambitious and tried to do with Vue.js and learn the framework in the process. Magic state updates were nice when it worked but with deeply nested models it always failed and I had to hack around to force it to update. I spent a ton of time fighting vue magic. I was ambitious. I wanted to make a generic NxN sudoku game where N was a url param.
Overall vue was like angular, done slightly well but it still had angular like problems where the magic failed and you had to dig very deep in code. It was also very slow to update the Dom. I had to revert to DOM element mangling just to speed up initial shuffle algorithm. I believe vue2 got on the vdom bandwagon so that’s nice.
I finally got it done, with two loooong nights.https://github.com/nojvek/uber-sudoku/blob/master/README.md
Uber did meet with me face to face but I didn’t want to move SF at the time and they didn’t have a Seattle office.
Overall vue has great ideas, probably good for a small project, but if you want to do a big SPA, I would not recommend unless you are really prepared to learn the internal magic.
Nowadays I really prefer preact. It’s the React api, it’s small, fast (has a better license - before Facebook got its shit together). One can read the entire source code in an hour or two.
It does one thing, it does it really well. This is what I like to see in libraries.
> They are supremely useful. Ultimately, it's knowing how to use them to their maximum potential.
Supremely useful for a typical full stack developer -- yes. Supremely useful for a dev team with members who specialize in web design (plain HTML, CSS, etc) -- not necessarily.
When your source code mixes a bunch of different web technologies it limits the types of developers who can effectively work on it.
Many commenters here regard React and Vue as "easy", but for many designers it's not easy. There are plenty of talented web designers who are just not interested or not capable of working efficiently with React/Vue.
Our company built an in-house JS component framework that is heavily inspired by React and Vue but that doesn't suffer from the intertwining of disparate web technologies. HTML, CSS and JavaScript stay separate from one another. As a result, our designers can independently iterate on UI without needing to touch a bit of JavaScript or quasi-JavaScript constructs.
There are global styles, and there are styles that are relevant only to a particular component. Hoist styles up to a global (or more general) layer whenever you can, but I really appreciate the fact that I know the important styles I need will be in the same file/folder.
I absolutely agree with you on that.
It's important to point out that grouping and intertwining are two very different things. If you are building a large client-side rendered JavaScript web app, then it is very beneficial to group together the JS, HTML and CSS for a particular component. That's what we do too. However, it is highly debatable whether the JS, HTML, and CSS should be intertwined together (i.e., literally mixed within the same lines) and controlled using framework-specific quasi-JS syntax. As I mentioned above, when you do the latter, you will unquestionably limit the types of developers who are able to work effectively with the code base.
If your team is comprised of a bunch of full stack developers, then you won't face much limitation. But if you're like us and your dev teams include web designers who are JS 'lightweights', then it's a problem.
Reading your other comment from above:
> I hate seeing code syntax mixed with markup syntax. You can end up with hard to parse views (reminds me of PHP and Rails), and abstracts the final HTML structure from the developer.
You hit the nail on the head -- I couldn't agree more.
Full disclosure: I'm a founder of Pagedraw, which lets designers make UIs as easily as they draw them in a design tool, but are production ready. The designers don't need any code, but programmers can connect it to Javascript data bindings/event handlers as needed.
No one has to write HTML/CSS by hand any more.
Edit: not sure why this is being downvoted, I am genuinely curious.
We do plan to eventually open source it, but there's a lot of work to be done before a public release: better documentation, better tutorials, remove some constructs specific to our company, etc. We've open sourced some of our internal JS libraries before and it's worked out well -- the contributions submitted and bugs reported by others have been very helpful.
Ease of use is a feature.
I think a much nicer way to work with templates is to see your markup with the same structure it will have once rendered, and attributes that describe those elements (just like real HTML attributes).
When it comes to accessibility, and creating predictable interactions without elements snapping around, I find it easier to visualize the end result when the markup isn't littered with text that won't be rendered.
HTML-in-PHP wasn't PHP. HTML-in-JSPwasn't Java. JSX in JavaScript is JavaScript. And that is a whole world of difference.
I haven't tried it yet but I'm definitely going to investigate mobx for my next react app.
That's what is great about Vue. It consolidates all the idiosyncrasies of the countless private frameworks that we've home-grown, and presents their features in a standard fashion that we can use across jobs. We can look at other people's code and understand it. It's exactly what experienced front-end developers do when they do it their way.
React is elegant and simple and I think most people understood it. I think they were less excited about the licensing, which was probably responsible for things like Vue and Preact. Personally I don't like Vue -- the "magic data" is touted as a plus, but IMHO it's room for confusion. At least when I setState in react, I can see the function call to "setState" implying I'm queueing a reactive change.
BAZINGA!
The inherent problem I run into with React is that it's "context-less", in the sense that the "React way of thinking" makes it hard to represent things like animations where you care about the previous state and how you got there. So in my case, I'm doing a multiplayer boardgame. Someone plays a card, I want to animate the card getting pulled from one deck and shuffled into another.
The best solution I've found so far is to add extra "annotations" (using terms loosely) into the current "board state" that represents the changes that happened, and that allows me to queue up the necessary animations. But that feels clumsy because it means persisting stateful data into the data structure alongside the actual "pure board state".
They both work on the principle of toggling the animation based on a property "show". It's pretty great!
But for me, the key question is which allows me to build faster. Does elegance mean I will spend so much less time fixing bugs that this benefit outweighs the much smaller amount of boilerplate required to put an app together in Vue? I don't really think so, but I haven't come to a firm conclusion either way yet.
It's also slightly more powerful.
- It has more functionality when it comes to JSX.
- It handles reactivity better.
However, judging the comments by Evan in Mays webcast. He mentions these two will be resolved by 2.6, 2.6-next.
I think the gap will be closed somewhat.
Never said you could not. The difference is that React is way more powerful and easier when building complex applications with JSX.
With Vue. I have a functional component that renders out JSX templates 6 levels deep and other DOM elements on-demand. All from a single multi-dimensional array.
In terms of the code count and simplicity. You couldn't achieve the same result with Single File Components so JSX to the rescue. But I'm sure someone could with SFC, but it would be such an over-engineered mess, it would be counter intuitive.
It was seriously difficult compared to what React offers because the functionality for Vue just isn't there. But I am sure in time, the functionality will be there. Starting with Vue 2.6/2.6-next.
Can you please explain a bit more on this?
I agree that it feels similar to those frameworks. I'm not put off by that because it's a framework that's clearly learned from all of the above and refined the forumla.
> This is highly stateful, object oriented, mutate-by-defualt, class based, imperative programming, with imperative DOM manual wirings
Vuex is a state management library similar to Redux which you can use to structure your app. Vue now has functional components, and there are libraries that let you process form data entirely from the store.
Have you never used $refs in React code? That's about as manual as I've seen Vue wiring get...
> separate templates from view logic (probably the biggest sin)
I think this is more a matter of taste. I really like that .vue files let you specify things like the kind of style loader (css/sass/less), script type, etc. Everything's still in one file, but each part is separate. I think (if ? then : else) stacked multiple levels in JSX looks pretty ugly. :)
> v-model="todo", this.$parent.$emit
v-model is just sugar for something like v-bind:value="todo" v-on:input="setTodo", which provides an initial value and makes a simple function that sets the component's todo property, similar to how you might call this.setState({...}) with React.
I was put off by this.$parent.$emit as well. You can simply pass the delete function as a prop in Vue as well, which is what I would do.
> implicit magic that makes list.push() update the view
This part is a little bit magic, but of course you could use Vuex for a more complex application. I was under the impression that excessive use of the analogous this.setState is frowned upon - am I wrong? Doesn't it do a bit of its own magic as well?
> While I don't personally prefer any of the above style, the point is not a criticism, but to point out that fundamentally Vue doesn't seem to offer any different core concepts than other frameworks.
Vue.js, Vuex, and Vue-Router are all maintained and released by a core team that coordinate changes. They all have pretty good documentation. I don't feel like Vue is fighting Javascript. I feel like there's usually an obvious way to do what you want to do most of the time. Nuxt.js (built on Vue) is incredibly simple to set up and offers an app skeleton, express templates, SSR, automatic rendering and plenty more.
> React's fundamentally paradigm and convention shift... [...] As a biased pattern match, most times I see people comparing React to Vue, they're new to both, and don't get React.
I had done a lot of messy jQuery stuff starting around 2006 or so. I played around with Backbone for a bit on the side, but found it messy. I tried to get into Angular 1 but found it overly complicated for little reward. I tried multiple times to get into React, but (and maybe this is less true now) after you choose the view layer, you still have to put together the rest.
I like functional components, explicit state management, and Vue + Vuex has those. I don't mind template syntax - I prefer it separated out into its own concern. It's not revolutionary, but I think it provides a solid, sensible foundation.
> Building Backbone apps where you glue events to DOMs written in strings with magic stateful data classes...
I've used Backbone some myself, and I agree that event handling is just plain messy. I don't have this problem writing Vue code.
Re: your last paragraph I rarely feel like I have a Vue problem because usually the way to do something is obvious. And when I do the errors are usually understandable, and Vue Dev Tools browser plugin is excellent. You can easily pick apart your app and Vuex state with it.
The other half is also programmer happiness, due to impedance matching with Rails.
I don't like Facebook that much either, but that doesn't mean they don't write useful software.
> The other half is also programmer happiness, due to impedance matching with Rails.
So impedance matching with a limited technology is a good thing? I find that to be... a limitation.
But, yes, utility is poorly correlated with ethics, at least in the short term. Longer term, maybe not. Ethical failure has a way of gumming up communication paths.
Not a sin.
> or, I suspect, don't fully understand
Your suspicion is wrong and so pointless I'm shocked this comment became the top one for this thread. Usually, pointlessly provocative stuff gets downvoted, as it should.
> React's fundamentally paradigm and convention shift.
You mean the paradigm shift of mixing HTML and JavaScript in the same hodgepodge? That's what we moved away from in the first place. React brought it back and many people convinced themselves that now it should work.
> React is so thin that it's rare to have a "React" problem, now I have vanilla "Javascript" or even "function" problems
Ah, this explains it. So deep into the... I don't want to say fanaticism but I can't think of another word, that there's even a preemptive rationalization of the technology's problems.
And this comes from someone who, over the last two years of experience, has taught himself to stop hating react by sheer force of will.
Are you talking about JSX? If so, this doesn't ring true to me; it isn't a mixture of HTML and javascript, it's just javascript with an HTML-like macro syntax. I've personally always found that really weird, but it isn't a hodgepodge, it's just normal javascript function calls with a weird syntax.
This is a distinction without a difference. The point is that putting HTML and JS logic in the same file is what was usually done in the early days of programming on the web, before separating code from event attributes into their own script tags and files became the norm.
All JSX does is the exact same mix in the opposite direction: it's not about JS inside HTML; it's HTML inside JS. And I understand that that's fine for many people -- and I've learned to stop caring -- but I take issue with pretending that it's a "paradigm shift".
Maybe your point is that you don't like the style of building up HTML strings by composing function calls. If so, fair enough, but I would argue that the jury is very much out on the trade-offs between that approach vs. an interpreter for a template language. React's string-building API is not the only example of this style; for instance lisps seem to do it that way pretty often (probably because sexprs are a quite natural syntax for this). Personally, I find the string-building approach much easier to reason about. It's a more explicit and well-defined problem. Instead of parsing and augmenting an existing string, the implementation just needs to transform some parameters to an output string.
As I said, I'm not really a fan of JSX itself because I find it weird (and unnecessary), but I do like the simple string-building API it gets translated into.
While I don't personally prefer any of the above style, the point is not a criticism, but to point out that fundamentally Vue doesn't seem to offer any different core concepts than other frameworks. I think it just hit a sweet spot timing of being a React competitor, when developers who didn't like (or, I suspect, don't fully understand) React's fundamentally paradigm and convention shift. As a biased pattern match, most times I see people comparing React to Vue, they're new to both, and don't get React.
I'm biased, but I'm biased through experience. Building Backbone apps where you glue events to DOMs written in strings with magic stateful data classes, and then scaling and debugging those apps, _sucked_. We didn't know any better back then, though, because we didn't have React to compare it too.
React can introduce problems (like any framework), but instead of trying to jump through hoops of convention, custom data binding and HTML tags, now my problems are my own. They're problems of composing functions or structuring my data flow. React is so thin that it's rare to have a "React" problem, now I have vanilla "Javascript" or even "function" problems, and it's such a breath of fresh air. Even when I'm debugging performance problems, I don't feel like I'm dealing with React, I'm dealing with comparing Javascript objects.