This article from Joe Zimmerman first appeared on appendTo’s blog.
Joseph Zimmerman (AKA Joe Zim) has been building web pages since he was 12. As he learned, he specialized in front-end JavaScript and has grown to be an expert. He blogs about what he knows on his own blog and several other blogs such as Smashing Magazine, Sitepoint, Tutsplus, and appendTo.
Vue.js’s popularity has been climbing pretty fast. It has about 3/4 the number of stars on Github as React, and more than double the stars of Angular. The watchers and forks are also pretty comparable, and while Vue.js hasn’t nearly caught up yet, you can see a definite trend of relatively rapid growth on Google Trends that is comparable to the growth of React and Angular earlier in their lives.
There must be a reason that Vue.js is growing so rapidly, especially when the JavaScript framework ecosystem is already filled with plenty of great frameworks. Vue.js doesn’t truly offer anything that other frameworks don’t already have, but it does bring together features from other frameworks in a unique way that may be a better combination. Which of these features did Vue.js glean from other frameworks, and from which ones?
Component-based frameworks
“Component-based” means that the framework is based around creating, composing, and nesting user interface building blocks called components. These components encapsulate everything to do with themselves rather than moving the logic out to a controller or something similar. Components go beyond view objects because they because they can be used directly in the templates as if they were HTML elements:
<template>
<div>
<h1>Some Title</h1>
<!-- This component is represented as an HTML tag -->
<my-component>
<!-- We're nesting components, just like in HTML -->
<button-component>Hello</button-component >
</my-component>
<another-component />
</div>
</template>
React is likely the primary source of inspiration for Vue.js in this area, though you could argue that Polymer and/or Web Components should be considered the inspiration here. I lean toward React primarily because Polymer is designed to actually create custom elements to be used directly in the HTML, whereas React and Vue.js use their components as if they were custom elements only in their templates (JSX in React’s case) and use the rendering engines and template compilers to only give the browser HTML elements that it already knows.
In the end, though, it doesn’t really matter who the idea was stolen from. What matters is that the declarative nature component-based systems are far simpler to use and compose than the imperative, old-school views and sub-views that came with Backbone.js and similar MV* frameworks.
Directives
Directives are a means of control flow and DOM manipulation that are built into the templates and look like HTML attributes. For example:
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
The v-for
attributes is a directive that loops through items
so they can all be displayed in li
elements. Angular and Aurelia do very similar things. In Angular, it would look like this:
<ul id="example-1">
<li ng-repeat="item in items">
{{ item.message }}
</li>
</ul>
And Aurelia looks like this:
<ul id="example-1">
<li repeat.for="item of items">
${ item.message }
</li>
</ul>
If you don’t have this kind of control capability embedded in the template syntax, the code becomes more difficult to read because you need to switch back and forth between the template syntax and the JavaScript’s syntax. Once again, the code is becoming more declarative instead of imperative.
Single, HTML-based file components
I wrote an article entirely about Vue’s Single File Components and the benefits they provide. It turns out, though, that Vue.js wasn’t the originator of this idea, at least not entirely. Vue.js stole this from Polymer/Web Components. Right on Polymer’s home page, halfway down the page, you’ll find an example that looks remarkably similar to a Vue.js Single File Component:
<dom-module id="contact-card">
<style>...</style>
<template>
<content></content>
<iron-icon icon="star" hidden$="{{!starred}}"></iron-icon >
</template>
<script>
Polymer({
is: 'contact-card',
properties: {
starred: Boolean
}
});
</script>
</dom-module>
Vue.js goes beyond this by allowing you to use alternative languages for the CSS (Sass, Less, Stylus, CSS Modules), HTML (Pug), and JavaScript (TypeScript, CoffeeScript) due to the required build step. The combination of all of these languages and technologies into a single file may be one of the greatest features for component-based frameworks due to being able to congregate everything related to the component into a single file for better maintenance.
Limited functionality for greater flexibility
Vue.js in and of itself is focused on rendering reactive and interactive user interfaces. It offers little in the way of structure or architecture. This is completely on purpose and it follows pretty much the same pattern as React in this regard. Like React, it lets other libraries handle the extra functionality, such as routing and more advanced, centralized state management. Unlike React, though, Vue.js provides officially supported libraries for some of these things, rather than leaving them up to third parties.
By removing this functionality from the core framework, you get a smaller file size and the flexibility to use other libraries if you want to. The trade-offs are that there are more choices to make and there isn’t necessarily one right way to do something because everyone is using something different. By officially supporting vuex and vue-router
Conclusion
Everything is based off of something that already exists, and Vue.js is definitely no exception. Despite having nothing new, though, Vue.js’s growth and popularity most likely came about because it stole and combined many of the best concepts from the other frameworks out there and kept out many of the things that cause headaches for developers.
I remember seeing Vue.js back when I was using Backbone epoxy. I think the initial versions of Vue were pretty heavily inspired by that library. Its kinda funny how frameworks haven’t really changed over the last few years.
inspired by, not stole from 🙂
Indeed. Ideas can’t be stolen.
Never write tired, you made a tiny duplication mistake in “Component-based frameworks” paragraph : “Components go beyond view objects *** because they because they *** can be used directly in the templates as if they were HTML elements”