
Using Vue.js and Rails - whitefang
https://www.classandobjects.com/tutorial/using_vue_js_with_rails/?utm_source=hackernews.com
======
buttminer
"Vue.js is awesome. I’m telling this after having used React for more than a
year in production software". I wish the author gave some mentions as to why
that's the case (and why he's even using Ruby here).

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.

~~~
vec
I'm not the author, but that quote lines up almost exactly with our
experience.

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.

~~~
ianstormtaylor
(Not familiar with Vue.)

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.

~~~
vec
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
The 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
> 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
Static 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
I 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.

~~~
ianstormtaylor
If you haven't watched it before, I'd recommend "Simple Made Easy" by Rich
Hickey. [0]

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.

[0]: [https://www.infoq.com/presentations/Simple-Made-
Easy](https://www.infoq.com/presentations/Simple-Made-Easy)

------
stevebmark

        <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?

~~~
aaron-lebo
Sometimes I get the impression that Vue is the new Angular that everyone is
excited about but people will be moving on from in 3 years. It's "my first
framework" kind of thing, or maybe it's a well-presented and complete package,
which has obvious value.

It would be interesting to see an informed comparison. What's Vue doing that a
million other frameworks aren't?

~~~
kirillseva
To me vue is like react but with

> 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

~~~
debaserab2
This is simpler syntax than JSX?

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.

~~~
kirillseva
they look pretty similar to me, one is kinda like js-in-html, the other is
html-in-js, to each their own.

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](https://github.com/facebookincubator/create-react-app) is great if you do
decide to go with React and want answers to aforementioned questions.

~~~
whitefang
In vue we have Vue CLI, which is becoming as powerful as create-react-app and
it also has nuxt.js [https://github.com/vuejs/vue-
cli](https://github.com/vuejs/vue-cli)
[https://nuxtjs.org/](https://nuxtjs.org/)

------
inopinatus
I have been progressively enhancing an older Rails+jQuery app with Vue.js
components, and integration has been a breeze.

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.

~~~
whitefang
So true. I've felt all these pains. :)

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...](https://stackoverflow.com/questions/43084499/replacing-rails-erb-
template-with-vue)

------
NathanCH

        // 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.

~~~
whitefang
haha. I'm really sorry for not using the right tools. I'm also sorry for my
bad English as I'm not a native English speaker.

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. :)

~~~
NathanCH
> 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 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.

------
enraged_camel
I share the author's sentiments. Vue is the first framework that actually made
writing front-end code pleasant. I sometimes even find myself looking forward
to it!

I use it with an Elixir/Phoenix backend and the two work incredibly well
together.

~~~
whitefang
I too would love to try Phoenix/Elixir. How is your experience using it?

------
fanpuns
Rails API + Vue is by far the most productive stack for me. I came from a
Rails background but never really liked the view layer + jquery. I tried React
but it just didn't stick. When I put those together for the first time though
I genuinely had fun building again.

------
vmware513
I just don't understand this hype around vue.js. People say, one of the best
feature of vue that it is somehow opinionated, howevever it has weird
templating syntax.

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.

------
luord
Similar experience, except using Flask. For new projects, I have a docker-
compose based template for that bootstraps postgresql, a flask app and a vue
app in different containers.

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.

------
sergiotapia
I prefer React and Mobx.

1\. Prettier - I can lint it. 2\. JavaScript - I can read it. 3\. Onboarding -
it’s easier to onboard a JavaScript developer.

~~~
vorpalhex
I prefer using `ed` to write pure ASCII C, obviously writing performance
sensitive parts in pure x86 asm.

/s

------
duiker101
Slightly off but is it just me or Ruby and Rails pretty much disappeared in a
puff of smoke after being all over HN for a while?

~~~
captain_crabs
Ruby on Rails has entered the 'boring' phase of the hype cycle, because it's
1) widely used 2) extremely reliable 3) lacking controversy. Have you used
ActiveStorage or ActionCable lately? They're brand new, probably not relevant
to HN at large, and awesome!

~~~
heartbreak
Adding to this, I have this blog post bookmarked from an HN post a few months
ago:

[http://www.codethinked.com/it-takes-all-kinds](http://www.codethinked.com/it-
takes-all-kinds)

It was made in response to a popular post claiming that Rails is “yesterday’s
software”.

~~~
wolco
The php community understands what you are going through. We made it through
you guys will too.

------
stevenwoo
I just started learning Vue.js, do you recommending switching to this gem
immediately or learning Vue.js fundamentals first then using the gem?

~~~
inopinatus
Not the author but I recommend trying it in a simple CRUD Rails 5.1 app with
the Webpacker gem version 3.0.2 or later, first running through the Vue
tutorial guide in that context. Once you've got a fuller understanding of how
it fits in, add webpacker to your existing app and starting building Vue
components.

Chris Oliver's guides on GoRails are also quite useful although they're
becoming out-of-date already in some aspects.

------
wnm
what I don't like about that setup is that views are rendered in the client,
instead of on the server.

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..

~~~
jeffjose
vue.js supports SSR out of the box, AFAI-can tell. Isnt that what you're
asking?

~~~
wolco
I think he wants a rails/vue hybrid backend. Why is another question.

