Using Vue.js and Rails
classandobjects.com
classandobjects.com
I've been using React with MobX and Typescript for the past year in production and it's been treating me and my team very well. The framework feels quite invisible at this point.
I also imagine this HN thread will quickly turn into a thread dominated by framework comparisons (it's the main reason I clicked through...)
I would update the article to include this.
First, Vue shares most of the things that actually make React exciting. Component oriented, one-way databinding, virtual DOM, a first party Flux-inspired state management plugin. We didn't feel that we lost anything moving from React to Vue, and most of our existing components were trivial to port.
What we gained, on the other hand, is a whole lot of developer comfort. Vue's template syntax can be read and manipulated by people who aren't primarily Javascript developers. Directives and filters eliminate quite a bit of boilerplate. Opt-in two way binding eliminates noisy setter functions without any loss of clarity. Getters enable the use of computed values as though they were raw data. There's no single killer feature, but taken together Vue just feels much more pleasant to use than React.
React has the correct fundamental abstraction, but the actual API mistakes "small" for "simple". JSX, in particular, is trivial to explain and understand in theory, but in practice is often quite verbose and complex to use, as everyone who has asked themselves "how do I actually write an if/else block" has discovered to their dismay. Vue plux Vuex keeps the same conceptual simplicity and cleanliness as React, but it pairs it with a much larger, much more opinionated API that doesn't force us to reinvent every wheel we need.
The way I look at it, it's not a contest. If Vue is better for some developers and some teams than React, that's great! It's nice to have multiple good tools to choose from.
When you talk about "template syntax" and "directives and filters" are those a non-full-JS-style of templates? As in can you execute arbitrary JS like you can with JSX? Just curious.
For me JSX is one of the biggest reasons that React is much, much better than Angular. I've found that once you get into re-implementing for loops, if statements, fallback defaults, etc., etc., for the sake of templating in an entirely new DSL, it becomes super complex and hard to learn/remember.
The nice thing is Vue allows you a choice rather than making it dogma. As another commenter said, this can come in handy in certain situations (e.g. dealing with forms).
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.
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.)
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.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} />`
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.The reason I say that is because you say "conceptually simple" as if that's a bad thing. Maybe we have to agree to disagree, but in choosing a framework I would much, much rather go for the one that is conceptually simple (at the cost of some extra verbosity in certain cases) over one that is conceptually complex but covers up that complexity with a terse-but-incomplete API.
You're not going to understand the benefits of the Vue vs. React choice by looking at idealized code samples, which is all your comment is showing. You'll only know it once you get into the edge cases. For example for list iteration in Vue...
- ...how do you change that example to omit the last item?
- ...how do you change that example to render a different element for every other item?
- ...how do you render something different if there are no items?
That's what makes the JSX approach simple. Once you understand that you can use any Javascript expression you want, you don't need to learn further. All of those questions can be guesstimated by a newcomer.
But with Vue you have to learn each and every "directive" and "modifier", and consult the docs again each time you forget them.
Just how Vue has JSX support I'm sure react could add template support. I personally wouldn't want anything to do with it as I find JSX a lot easier to work with but it wouldn't be that hard to do.
vue is "easier" with probably less boilerplate at the cost of more magic and less type safety due to magic string templates (if using typescript like I love to)
Definitely not a good tradeoff for me, but it is for some.
How is Vue easier if we only consider components?
How can it offer something simpler than functions as components?
For example, Backbone is much simpler than React. React keeps a full virtual copy of the DOM in runtime and uses complex diffing algorithms to decide when and how to actually update the DOM in a manner which is entirely opaque to the developer. Backbone just does the DOM updates you tell it to, when and how you tell it to. And since Backbone is so much simpler, it logically follows that building an application in Backbone much be much easier than building the same application in React, right? Right?
In Vue, a component generally consists of a raw JS object, an (almost) HTML template, and a block of raw CSS. The framework does some opaque but straighforward work to bind these three together into a single conceptual entity. This is indeed more complex, but the added complexity follows the grain of my preexisting intuitions. The end result, in practice, is components which have a clean internal structure and much less boilerplate. Slightly more complex, but easier.
Yes, there is redux-form but the fact that it exists seems like a drawback for React and Redux. Its APIs can be very clunky and not straightforward at all. setState(...) is not a good solution either as things can get more complicated with nested objects and such.
In Vue, you don't even think about this problem. There's v-model which makes forms a breeze.
Had the exact same experience. After Angular 1, Ember, and React, Vue is the first JS framework that I'm actually excited to use. My three biggest gripes with React are solved with Vue 1) better out-of-the-box experience (CRA is still not ideal), 2) single file components that strike a great balance between templating, logic, and styling, 3) Vuex is a slick Flux architecture with much less boilerplate than something like Redux.
Vue is opinionated enough to give you a sane structure and guidance, but not so opinionated that you feel trapped in their domain and get lost in domain-specfic magic. You might say it's the goldilocks of frameworks. Doesn't introduce any radical new ideas, but MAN does it strike the right balance.
<el-form :model="user" :rules="rules"
I would still rather write lintable, composable Javascript (JSX) than an embedded mini string language in HTML attributes.This is a strange post, it's even less information than a Vue 101 post?
Your IDE should be able to syntax highlight and even lint it.
People have reported some issues with the Vue tooling, but it's worth trying:
brew cask install webstorm
cd your-app && webstorm .It would be interesting to see an informed comparison. What's Vue doing that a million other frameworks aren't?
> simpler syntax. I think single-file components is a great thing when you're getting started. While true "js ninjas" will call me out on this, they're probably employed by a large org with problems that are different from mine.
> less choice. I only write frontend occasionally. How would I know which react-router to choose? What's the best redux package? What about handling CSS, what's the flavor du jour? Vue says "want something done - do this. here's vue router, vuex, etc."
Overall, the two are very much similar in both how they work and what they provide, but one is developed and used by an organization that has a virtually infinite supply of engineers, and the other is being developed by one guy.
Technology that makes Facebook successful may be inappropriate for a successful hackathon or a small startup
Vue:
<v-chip v-if="manager.department == 'Engineering'" color="primary" text-color="white" small>{{ manager.department }}</v-chip>
JSX: if (manager.department == 'Engineering') {
return <VChip color="primary" text-color="white" small>{manager.department}</VChip>
}
I dunno about you but I grok code that uses whitespace, braces, and parenthesis to identify branching logic way faster than tag attributes.a) you can write JSX in Vue components since that's your preference, and this is explicitly documented and supported: https://vuejs.org/v2/guide/render-function.html#JSX, and
b) that first example violates the Vue style guide. https://vuejs.org/v2/style-guide/
return ( manager.department === 'Engineering' && <VChip color="primary" text-color="white" small>{manager.department}</VChip> )I'm talking more about the whole experience of building out a full app. How do I structure my codebase? Which packages should I use in 2017? It's a much more trivial exercise with vue if you're only doing frontend work occasionally and not as part of your normal job.
I have to point out that https://github.com/facebookincubator/create-react-app is great if you do decide to go with React and want answers to aforementioned questions.
It'll swing back in another few years. As it always does.
It's not the new Angular. AngularJS was basically the only game in town for a while. React is more popular than Vue, current. And it has Facebook behind it. Angular 2+ has Google behind it. Vue remains an independent underdog.
Plus, having used Vue in production for over a year and React on personal projects, they are incredibly similar. Create an object, give it properties, lifcycle hooks, methods, and a template to render, then chuck it into an html file. React users prefer JSX, but Vue can use JSX just as well.
React and Vue have similar ecosystems around them. Redux for React, Vuex for Vue. React-router vs vue-router. A simple http/ajax lib for making API calls are present for each. React has React Native, Vue has Weex.
Lastly, Vue is super easy to adopt, bit by bit; and it has incredibly well-put-together documentation. All of these things hardly indicate to me that it's going to become abandonware as soon as another framework comes around.
Admittedly, React is a little bit more mature than Vue; but what's React doing that Vue isn't? What's Angular doing that those two aren't? Or Aurelia? Or Mithril?
I've personally preferred React+Redux+Typescript for new personal projects, but when facing a task of modernizing e.g. Angular apps, Vue is much more attractive.
In what way is that a demonstration of flexibility?
> ability to easily leverage existing HTML/Pug/CSS/SCSS/etc, making it an easier target to migrate to.
How is it any easier than React? Seems the exact same to me.
By accommodating developers with various preferences. You can have typechecked classes with TSX like React, or self-contained components leveraging traditional HTML/CSS, which is how Angular components are structured.
> How is it any easier than React? Seems the exact same to me.
There are many similarities between Vue and Angular, especially regarding the DSL in templates. Whereas going from Angular to React is a significant rewrite.
Things I'll note:
- Rails effectively now has two asset pipelines. Sprockets has been the off-the-shelf inclusion for some years. The Webpacker gem is making Sprockets look out-of-date and under-maintained. Adding Vue to the existing project has been trivial, using Webpacker. At some point, somethings gotta give and we choose one or the other. My money is on Webpacker.
- Vue components are very readable. For a Rails-first developer looking to be productive this has been a huge win over the other "big three" comparable frameworks.
- Building a real-time control panel with ActionCable and Vue was amazingly easy - there was no impedance mismatch between the client and server side - and the result is surprisingly reliable and extremely performant even for mobile clients with patchy connectivity. The hardest part was finding the right nginx+ELB configuration to handle the Websockets upgrade.
- One of the first things I always seem to build is higher-level abstractions for forms, such that (for example) client- and server-side validations render with consistent L&F and without POLA violations in the UX. Vue gives some excellent primitives to assist e.g. v-model, but some kind of next-level abstraction for forms is an obvious next step for the integration.
- I see the peanut gallery is sledging the "template language", not realising that one may switch template formats with ease. I've seen Vue components written in JSX, Haml, Pug et al. Obviously it's better if a team standardises, but complaining about the "template language" means you missed a full understanding of what you're looking at.
- Turbolinks is, as usual, a pain in the ass. By reimplementing basic web browser functions such as navigation and page caching as a frankly premature optimisation, Turbolinks introduces numerous incompatibilities and misbehaviours. There are compatibility shims, but adding and maintaining such for every glitch your users encounter is gonna suck for everybody. Top tip, if you're using Vue with Rails, disable Turbolinks.
About choosing one asset pipeline, what if the Vue could be the new ERB?
Here I have a question on the same. I would love to work on this. https://stackoverflow.com/questions/43084499/replacing-rails...
// ignore this line, it just says hey Vue use the element UI
This tutorial is full of hacks, confusing comments, and questionable english. Also I wonder if the author knows he or she can use multi-line HTML comments.I honestly don't see the issue with JSX when looking at "html" like this.
and yes, multi-line comments are there but in atom, I can just use ctrl + / to comment and uncomment, makes my life lot easier. I would say it's not huge.
If you can help me by telling which comments are confusing I would love to work with you and fix that. Thanks for your constructive feedback. :)
I am dying of laughter.
Also, re: JSX. I was surprised now to see Vue supports JSX out of the box, so that's pretty cool.
I use it with an Elixir/Phoenix backend and the two work incredibly well together.
The conclusion is simple again. There is only one framework left which is "rule them all", opinionated, super easy to use, with beautiful templating language, an fast. Fast rendering, fast for building apps, and the only with continous consistency. It is Ember.js. Obviously.
Aside note: Why is every article featured here about vue filled with people... talking about how they prefer using react? I don't see how it isn't annoying for everyone else and for themselves: I don't care about react and, thus, I don't read or even open links about it.
1. Prettier - I can lint it. 2. JavaScript - I can read it. 3. Onboarding - it’s easier to onboard a JavaScript developer.
/s
And those that do, they are on forums to learn about new exciting shiny frameworks/languages, like Elixir
http://www.codethinked.com/it-takes-all-kinds
It was made in response to a popular post claiming that Rails is “yesterday’s software”.
Heroku free tier + hobby dev pg + Phoenix channels = 27000 concurrent users before Postgres starts complaining
We've now entered the ML/AI wave, which will last for a few months until people get bored and start getting excited for the new new thing (WebAssembly and the C/C++ toolchain? VR? Bitcoin?).
I'd be very interested in reading about your (and other's) experience in making the transition to Clojure.
My personal experience is probably not very representative. I was doing Rails up until I began working on cleancoders.com 5 years ago, which was entirely written in Clojure using Compojure.
Honestly it's not that much different than working in Express.js these days, considering all the improvements to the JS language and ecosystem. Ruby has Sinatra too which is pretty comparable to Compojure and Express.
There's also something to be said for the novelty effect. Many people who went from Ruby to Clojure went from Java to Ruby because of the novelty, and probably went from Ruby to Clojure for the same reason, and at least a few of them have since moved to Elixir for probably the same reason.
It's pretty lame painting other developers as idiots. If you can't identify with the common complaints about Rails, then you haven't used it long enough.
The question isn't whether it has warts or not. Of course it has them. The question is whether or not they're worth it to you.
Chris Oliver's guides on GoRails are also quite useful although they're becoming out-of-date already in some aspects.
TL;DR; Learn Rails and Vue in isolation. When building sofware use this gem.
I wish there was a js framework, which would let me keep renderering my views with rails on the server, but then take over and help me handle ui interactions etc..
If this interests you, I would love to work. :)