Hacker News new | ask | show | jobs
by nek4life 2679 days ago
> and has a very wierd concept of how objects work in JS.

What is so weird about it? I personally find Vue vastly more approachable than React is, especially once you have to start writing all the plumbing to get all the libraries you need to go along with it to write a real world app.

> ] It's a templating system with its own rules and mini-DSLs that ends up being compiled into JS.

Vue has the option to use Webpack to compile html compliant templates to JS functions just like JSX (which BTW is not JavaScript and not HTML compliant and is also a separate concept that needs to be learned as well.)

CSS is just another add-on through Webpack when using Single File Components. Nothing really ground breaking here except for the fact that it creates a nice separation of concerns. This is especially true on teams with junior devs or designers. Or with a team that works on a site with mixed MPA and SPA features.

1 comments

> What is so weird about it?

I go a bit in depth here: https://news.ycombinator.com/item?id=17471199

> Vue has the option to use Webpack to compile html compliant templates to JS functions just like JSX

Vue's templates are not HTML-compliant. They are just that: templates. That get compiled to JS anyway.

> JSX (which BTW is not JavaScript and not HTML compliant and is also a separate concept that needs to be learned as well.)

JSX is a very thin DSL on top of Javascript. It's just function calls: https://reactjs.org/docs/react-without-jsx.html

Once you understand that, everything falls into place.

> CSS is just another add-on through Webpack when using Single File Components.

It's not a webpack add-on. It's a part of Vue's templating engine that is essentially CSS-in-JS, they just give you a template to work in.

> It's not a webpack add-on. It's a part of Vue's templating engine that is essentially CSS-in-JS, they just give you a template to work in.

It's regular CSS in the templates and regular CSS in the frontend. There's no JS involved anywhere, unless you count the tooling, but we already use JS tools for CSS processing (PostCSS).

Scoped CSS is an old HTML5 feature that was dropped in favor of style encapsulation using Shadow DOM/Web Components.

I thought one of the beauty of vue template is 'It is not complete set of JavaScript logics, only subset that just able to support proper html structure.'.

It means you can't abuse JavaScript everywhere, creating totally unreadable render function, nest array mapping in Ternary operator and reduce it to what the hell no one can read and destroy all the readabilities.

For me, for you, for everyone, if you using that syntax, then it is simply readable just like html.

Less powerful, but the management definitly worth more.

> I thought one of the beauty of vue template is 'It is not complete set of JavaScript logics, only subset that just able to support proper html structure.'.

The problem with all templating systems is that they start with "we need to limit the amount of logic". But all templating systems find out that this is extremely limiting. So they grow. And grow. And grow. And grow.

Same with Vue. The amount of special cases and custom things just grows and grows. See my comment here: https://news.ycombinator.com/item?id=19199423

You need simple conditional logic. So you end up with v-if and v-else. Then you have to add v-if-else.

You need loops. So you end up with a custom DSL for v-for. And then you expand it to also work on objects. And you need to bind to object produced inside the for loop. And...

And you need to handle events. But events are anything but simple. You need to prevent them, you need to stop or start propagation, you need access to their properties. So you end up with v-on:click.stop.prevent. And function calls. And magic variables in the form of $event.

Worse still, all your existing knowledge about how to apply these concepts in JS is void. Template has taken over.

So in the end you end up with a system that is not really HTML, not really JS, but a weird combination of the two. And the amount of concepts is not exactly more readable than plain React that just uses JS everywhere.

Yes, that is the beauty. And when you really do need the full power of render functions Vue has those too.

https://vuejs.org/v2/guide/render-function.html

> I go a bit in depth here: https://news.ycombinator.com/item?id=17471199

I've read this before. Vue is a framework. It also has a templating system that is not JavaScript, it's valid HTML with attributes that tell Vue how to bind to it. It's really not that difficult.

> Vue's templates are not HTML-compliant. They are just that: templates. That get compiled to JS anyway.

Sorry, but you're wrong here. They are valid HTML.

https://vuejs.org/v2/guide/syntax.html

"Vue.js uses an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying Vue instance’s data. All Vue.js templates are valid HTML that can be parsed by spec-compliant browsers and HTML parsers."

> JSX is a very thin DSL on top of Javascript. It's just function calls: https://reactjs.org/docs/react-without-jsx.html

IMHO only the simplest of components featuring JSX that don't read like a spaghetti PHP coding nightmare to me. For the small number of times you actually need the full power of JavaScript you could also use JSX in Vue with a render function if necessary. I personally prefer to keep my templates and logic separate when possible.

> It's not a webpack add-on. It's a part of Vue's templating engine that is essentially CSS-in-JS, they just give you a template to work in.

No, it's not part of the template engine, it's part of vue-loader which is used by Webpack to create single file components.

https://github.com/vuejs/vue-loader

> it's valid HTML with attributes that tell Vue how to bind to it. It's really not that difficult.

You mean it has at least three JS-like DSLs (which are not JS, and have different rules depending on which context they are in). In addition it has a very weird binding system which I described at length in the linked comment.

Yup. "Not that difficult".

Meanwhile JSX is a single consistent DSL that directly maps to function calls:

   <Tag prop=(string or valid Javascript expression)>
      other tags, strings, or valid Javascript expressions
   </Tag>
That's it. Even "html-like" attributes that people seem to not like... are exactly what HTML attributes are in actual Javascript DOM APIs [1] [2]

The amount of custom attributes, custom DSLs and gotchas just in the "HTML" part of Vue is staggering in comparison: https://pbs.twimg.com/media/DbVEoKOX0AEEen6?format=jpg&name=...

And funnily enough it ends up being compiled to what React is in the first place (here's the output of a Hello World app in Vue):

    var render = function() {
      var _vm = this
      var _h = _vm.$createElement
      var _c = _vm._self._c || _h
      return _c(
        "div",
        { attrs: { id: "app" } },
        [
          _c("img", {
            attrs: { alt: "Vue logo", src: require("./assets/logo.png") }
          }),
          _c("HelloWorld", { attrs: { msg: "Welcome to Your Vue.js App" } })
        ],
        1
      )
    }
Look, it's exactly what React without JSX is [3]. Only in React you don't need to invent a custom scripting language and binding rules.

[1] https://developer.mozilla.org/en-US/docs/Web/API/Element/att...

[2] And I'm really sad to see React team seriously discuss caving in to mob and considering replacing className with class etc.

[3] https://reactjs.org/docs/react-without-jsx.html

> That's it. Even "html-like" attributes that people seem to not like... are exactly what HTML attributes are in actual Javascript DOM APIs [1] [2]

The attributes / DOM properties in JSX are also a mixed bag and not consistent. See https://github.com/facebook/react/issues/13525#issuecomment-...

> Look, it's exactly what React without JSX is [3]. Only in React you don't need to invent a custom scripting language and binding rules.

JSX is a custom extension to JavaScript. It's not part of JavaScript or intended to be part of the spec or implemented in browsers. In fact, you have to use some sort of transpiler in order to use it. So, it's not just JavaScript.

> https://pbs.twimg.com/media/DbVEoKOX0AEEen6?format=jpg&name=....

There's really nothing that complicated in here, if you're familiar with Vue. In fact, it's really easy for me to see what's going on at a glance in one place, which is my personal preference. From my own experience, that's rarely the case when working with React the way JSX tends to get broken up because it doesn't have something as simple as a standard if conditional statement within JSX itself.

I've never claimed you do not need to learn anything when working with Vue templates, you need to understand how the system works, but it took me all of a few hours to understand. The features and benefits that I prefer over React/JSX make that worth it to me.

> JSX is a custom extension to JavaScript. > In fact, you have to use some sort of transpiler in order to use it. So, it's not just JavaScript.

Yes. However, one thing you fail to see is that it directly compiles to function calls.

   <Tag a="b" x={y+z}>{valid JS expression}</Tag>
is

   React.createElement(Tag, { a: "b", x: y + z }, [<valid JS expression>])
Which means:

- you have access to JS variable in scope

- you can use JS facilities (proper if/switch statements, for loops, functional programming, you name it)

- you need no additional scripting or templating features. It's, well, just Javascript.

However in Vue (emphasis mine):

> There's really nothing that complicated in here, if you're familiar with Vue.

Yes. Exactly. If you're familiar with Vue

So:

- custom tag attributes: v-bind, v-if, v-for, v-on, v-show, v-model... (I honestly don't know how long this list is)

- custom attribute shorthands: :key, @key

- attribute extensions: v-on:keypress.prevent

Inside attributes you can have:

- Javascript expressions (much like React inside {})

- or magic binding:

    v-bind:href="url", v-if="seen" etc.
- or JS-object-like magic bindings which resolve to a string:

    v-bind:class="{ active: isActive, 'text-danger': hasError }"
- or JS-array-like magic binding that gets resolved to a string:

    v-bind:class="[activeClass, errorClass]"
- or a magic array with objects that gets resolved to a string:

    v-bind:class="[{ active: isActive }, errorClass]"
- or a separate DSL for v-for:

    v-for="(item, index) in items"
- or a separate DSL for v-for where you can bind entities from the DSL (which looks exactly like the magic binding to data from the component, what happens when they clash?):

    v-for="(item, index) in items" :key="items.id"

- or JS expressions that may be function references that may be things that look like function calls but actually aren't:

    v-on:click="counter += 1"

    v-on:click="greet"

    v-on:click="say('what')"
- with special magic variables

    v-on:click="warn('Form cannot be submitted yet.', $event)"
- with special magic modifiers

    v-on:click.stop.prevent="doThat"

"It's not that difficult" ©™ And the list above doesn't include the overview of the JS code that underlies components in view. It's another whirlwind of magic and non-magic: https://news.ycombinator.com/item?id=17471199

Oh yes, and this gets compiled down to some JS that bears little to no resemblance to original code.

And somehow people complain about how React is difficult. Wat?

> Yes. However, one thing you fail to see is that it directly compiles to function calls.

I understand how JSX works, stop patronizing me. The only thing I fail at is seeing how any of your examples are complicated or have magic so deep that you need to continue to burn Vue at the stake for. In fact, I find your Vue template examples completely intuitive and easy understand with minimal time invested in learning how Vue templates work. It's my preference to spend a little bit of effort up front learning how Vue templates work in order to have clearer separation between business logic and templates.

> JSX is a very thin DSL on top of Javascript.

With its own syntax. Which looks like HTML but isn't.

Considering the differences lean towards the DOM interface names for given attributes and properties, I wouldn't exactly call it NOT JS.

It's actually an XML abstraction that closely resembles HTML + JS-DOM, and is then converted into function calls and arguments.

It's also about as close to E4X as an abstraction that I've seen and something I wish was cross browser over a decade ago when it was first introduced by Mozilla and Adobe, but that's a long side-track. In the end, it's very effective and works well imho. Yes there are some more complexity points in some places, but I don't think anything else does it better. Vue imho is comparible, but I don't like it as much and I feel that Angular is far worse in practice.