{"id":13844,"date":"2016-07-06T12:15:25","date_gmt":"2016-07-06T09:15:25","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=13844"},"modified":"2016-07-05T23:16:36","modified_gmt":"2016-07-05T20:16:36","slug":"consider-vuejs-next-web-project","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/","title":{"rendered":"Consider VueJS for Your Next Web Project"},"content":{"rendered":"<p>Whether or not you\u2019ve ever heard of <a href=\"https:\/\/vuejs.org\/\">VueJS<\/a> before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for <a href=\"http:\/\/pages.codeship.com\/docker\">our Docker-builds UI, Jet<\/a>.<\/p>\n<h2>What Is VueJS?<\/h2>\n<p>To get a rough idea of what Vue (pronounced \u201cview\u201d) does, think about it as the \u2018V\u2019 in an MV* pattern. If you\u2019d like to compare it to something else, it\u2019s probably closest to <a href=\"http:\/\/reactjs.net\/\">React<\/a> but with a far lower barrier of entry. No need to learn something like <a href=\"https:\/\/jsx.github.io\/\">JSX<\/a> or pre-compile files just to give it a try. Drop it into your HTMLs header like any JS library, and you\u2019re all set. Templating will probably look familiar to anyone who has worked with Angular or Mustache in the past.<\/p>\n<p>So let\u2019s talk about what made VueJS so attractive for us at Codeship.<\/p>\n<h4>Data-driven versus DOM-driven UIs<\/h4>\n<p>Separation of concerns is a common term in software engineering. Yet when it comes to UIs, we see code like this all too often:<\/p>\n<pre class=\"brush:php\">function textReturningFunction () {\r\n  return 'Hello World!'\r\n}\r\n\r\n\/\/ Set some text in jQuery\r\n$('.someElement').text(textReturningFunction())<\/pre>\n<p>I wrote JS like this for a long time early in my career. But if you think about it, this code is pretty far removed from the idea of separation of concerns.<\/p>\n<p>The JS has to know a lot about your markup and the general structure of the DOM. At any given time when the markup changes \u2014 <code>.someElement<\/code> gets renamed to <code>.some_element<\/code>, for example \u2014 your JS will break. The function that\u2019s actually returning the data we want to show did not break though. It\u2019s still returning <code>Hello World!<\/code> when called. In this instance, the data is the same, but the binding is broken. This happened because the JS is DOM driven.<\/p>\n<p>Let\u2019s look at a simple VueJS instance that should print out the same text as above.<\/p>\n<p><strong>The Markup:<\/strong><\/p>\n<pre class=\"brush:php\">&lt;div class=\"app\"&gt;\r\n  &lt;span class=\"someElement\"&gt;\r\n    {{ msg }}\r\n  &lt;\/span&gt;\r\n&lt;\/div&gt;<\/pre>\n<p><strong>The JS:<\/strong><\/p>\n<pre class=\"brush:php\">new Vue({\r\n  el: '.app',\r\n\r\n  data: {\r\n    msg: 'Hello World!'\r\n  }\r\n})<\/pre>\n<p>The Vue instance is a simple object. Running this code will do the trick, and you\u2019ll find <code>&lt;span class=\"someElement\"&gt;Hello World!&lt;\/span&gt;<\/code> on the page. If the class on the <code>span<\/code> would change now, it will not break the JS because the class is not referenced.<\/p>\n<p>To stay true from the start, we still referenced an element in our Vue instance. The <code>.app<\/code> element is the entry point from which Vue will handle things. If that one gets changed, the reference needs to be updated as well.<\/p>\n<h4>Reactivity<\/h4>\n<p>All variables in Vue are reactive. This means they are observable and can have watchers attached. Variables that change will automatically inform their peers of the change. On the VueJS side, there\u2019s actually <a href=\"http:\/\/vuejs.org\/guide\/reactivity.html\">a very detailed description of this system<\/a> that I highly recommend you read.<\/p>\n<p>For quick understanding, compare Vue\u2019s behavior to dirty checking in Angular. If something changes in Angular, it\u2019ll start to search for that change. It\u2019ll compare new values with old until no more changes are found, and it will update what\u2019s necessary. This takes time and eats up resources while correlating with the complexity of the application.<\/p>\n<p>A reactive data system like Vue uses may need more initiation time upfront, but that\u2019s a good price to pay.<\/p>\n<h4>Components<\/h4>\n<p>Vue\u2019s flexible but simple system is built around the concept of components. Components are small, reusable parts of the UI. Actually, this should be nothing new \u2014 the majority of JS frameworks these days are built around that concept. Web Components are a known solution for quite some time now. The problem is always the browser-wide implementation.<\/p>\n<p>Vue takes care of this by providing a browser-independent component system. This system is straightforward to use and falls in line with the rest of Vue\u2019s structure.<\/p>\n<p>!New Call-to-action<\/p>\n<h2>Why We Chose VueJS<\/h2>\n<p>Inside the Codeship application, we have one high-load and interaction-heavy page: It\u2019s the build detail page of our Docker-based build infrastructure (<a href=\"http:\/\/pages.codeship.com\/docker\">Jet<\/a>), letting the user read terminal output. The challenges of this page after the initial release included:<\/p>\n<ul>\n<li>Fix the performance problems we were facing (frozen browser)<\/li>\n<li>Allow efficient rendering of objects (10K+)<\/li>\n<li>Make the code behind the system more accessible<\/li>\n<li>Keep the overhead of introducing a new technology small<\/li>\n<\/ul>\n<p>For the first implementation, we used Angular. The terminal output consisted of a large string coming from the server. On the client, that string got transformed and rendered onto the page in one process. When we tried to use objects for rendering, Angular wasn\u2019t performing well enough. At a certain number of lines, those logs where so big that they could crash the browser. After some investigation, we were able to trace this back to the scope used by Angular. The sheer number of lines was not the issue, but rather that Angular tried to keep track of the whole DOM and all its changes.<\/p>\n<p>We needed a new tool that didn\u2019t care for the DOM in a way that allowed it to crash like that. Also, we couldn\u2019t afford to greatly change how we handled assets, by introducing new build tools or attaching new infrastructure. Vue seemed like it would fulfill those needs.<\/p>\n<p>A rough prototype with large HTML files (more than 1MB) dumped into the browser was promising. No impact on the performance of the page was noticeable. In the next iteration, we tried to render HTML based on plain JS objects. Ten thousand lines were no problem at all. After some further testing and a pros\/cons list, it made sense to move forward with Vue. Let me show you what we did.<\/p>\n<h2>Starting Simply with VueJS<\/h2>\n<p>Our first iteration of rebuilding focused on preparing the base structure of the build detail page of Jet; our first goal was to render the sidebar of the page. This sidebar contains steps and services that are clickable elements following a given structure, in this case, an HTML structure.<\/p>\n<pre class=\"brush:html\">&lt;!-- Application Example --&gt;\r\n&lt;div id=\"app\"&gt;\r\n&lt;aside&gt;\r\n&lt;ul class=\"services\"&gt;\r\n&lt;li v-for=\"service in services\"&gt;\r\n{{ service.name }}\r\n&lt;\/li&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/aside&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>Notice how easy this small snippet of HTML is to read. Even if you\u2019re not familiar with the exact syntax of Vue, the code makes sense. For every <code>service<\/code> object out of the array <code>services<\/code>, we plan to render a <code>li<\/code> element with the name of a service.<\/p>\n<p>Let\u2019s see what the Vue code would look like:<\/p>\n<pre class=\"brush:php\">new Vue({\r\n  el: '#app',\r\n\r\n  data: {\r\n    services: [\r\n      {name: 'first service'},\r\n      {name: 'second service'}\r\n    ]\r\n  }\r\n})<\/pre>\n<p>When firing up the browser, the result is as you would expect:<\/p>\n<pre class=\"brush:html\">&lt;!-- Rendered HTML --&gt;\r\n&lt;div id=\"app\"&gt;\r\n&lt;aside&gt;\r\n&lt;ul class=\"services\"&gt;\r\n&lt;li&gt;first service&lt;\/li&gt;\r\n&lt;li&gt;second service&lt;\/li&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/aside&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The next step is leveraging components:<\/p>\n<pre class=\"brush:html\">&lt;!-- Application Example --&gt;\r\n&lt;div id=\"app\"&gt;\r\n&lt;aside&gt;\r\n&lt;ul class=\"services\"&gt;\r\n&lt;!-- Placeholder for the component --&gt;\r\n&lt;jet-service v-for=\"service in services\" v-bind:service=\"service\"&gt;&lt;\/jet-service&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/aside&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The components in Vue fall into place quite easily:<\/p>\n<pre class=\"brush:php\">var JetServiceComponent = Vue.extend({\r\n  name: 'jet-service',\r\n\r\n  props: ['service'], \/\/ made available by v-bind:service=\"service\"\r\n\r\n  template: `\r\n    &lt;li&gt;\r\n      &lt;strong&gt;{{ service.name}}&lt;\/strong&gt;\r\n    &lt;\/li&gt;\r\n  `\r\n})\r\n\r\n\/\/ Register that component in our Vue Object\r\nnew Vue({\r\n  el: '#app',\r\n\r\n  data: {\r\n    services: [\r\n      {name: 'first service'},\r\n      {name: 'second service'}\r\n    ]\r\n  },\r\n\r\n  components: {\r\n    'jet-service': JetServiceComponent\r\n  }\r\n})<\/pre>\n<p>Running our updated code in the browser will eventually produce the following output:<\/p>\n<pre class=\"brush:html\">&lt;!-- Rendered HTML with components--&gt;\r\n&lt;div id=\"app\"&gt;\r\n&lt;aside&gt;\r\n&lt;ul class=\"services\"&gt;\r\n&lt;li&gt;&lt;strong&gt;first service&lt;\/strong&gt;&lt;\/li&gt;\r\n&lt;li&gt;&lt;strong&gt;second service&lt;\/strong&gt;&lt;\/li&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/aside&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>What should be obvious so far is that using VueJS is very straight-forward. There\u2019s no need for a lot of boilerplate code to get started. The only thing you need is a good understanding of JS objects and functions.<\/p>\n<h2>Adding Complexity with VueJS<\/h2>\n<p>The <code>jet-steps<\/code> component was a little more complex. Steps can be grouped and nested, and the structure is probably different for every project. Let\u2019s proceed by aiming for the following structure:<\/p>\n<pre class=\"brush:php\">-- some step\r\n-- step group\r\n  -- grouped step alpha\r\n  -- grouped step beta<\/pre>\n<p>or as JSON<\/p>\n<pre class=\"brush:php\">[\r\n  { name: 'some step', type: 'step'},\r\n  { name: 'step group', type: 'group_step', steps: [\r\n    { name: 'grouped step alpha', type: 'step'},\r\n    { name: 'grouped step beta', type: 'step'},\r\n  ]}\r\n]<\/pre>\n<p>The component should be able to self-invoke based on the structure, making it a little more complex. The Vue object uses specific key values for structuring. During the setup process, <code>getters<\/code> are made available that can then be used in a template. The <code>computed<\/code> key allows us to store functions on the Vue object that return computed values. Let\u2019s use a function for checking whether a step is a group step:<\/p>\n<pre class=\"brush:php\">var JetStepsComponent = Vue.extend({\r\n  name: 'jet-step',\r\n\r\n  props: ['step'], \r\n\r\n  computed: {\r\n     isGroupStep: function () {\r\n       return this.step.type === 'group_step'\r\n     }\r\n  },\r\n\r\n  template: `\r\n    &lt;li&gt;\r\n      &lt;span&gt;{{ step.name }}&lt;\/span&gt;\r\n      &lt;ul v-if=\"isGroupStep\"&gt;\r\n        &lt;jet-step v-for=\"step in step.steps\" v-bind:step=\"step\"&gt;&lt;\/jet-step&gt;\r\n      &lt;\/ul&gt;\r\n    &lt;\/li&gt;\r\n  `\r\n})<\/pre>\n<p>You may have already guessed how the Vue object would look. Vue is not getting more complex to allow nested components. There\u2019s a line written by <a href=\"https:\/\/twitter.com\/youyuxi\/status\/735109888930648064\">Evan You<\/a>, the creator of Vue, that I want to quote here:<\/p>\n<blockquote><p>Thoughts on simple versus easy: Why not make it simple AND easy?<\/p><\/blockquote>\n<p>This is exactly what Vue tends to do, and it does it really well.<\/p>\n<h2>VueJS Performance<\/h2>\n<p>At this point, let\u2019s step away from looking at the syntax of Vue and see where it outshines our previous implementation. Performance was the biggest issue as I mentioned earlier. The UI should show a large amount of terminal output to the user.<\/p>\n<p>I ran some benchmarks on the performance at certain steps of the development process. The test generates 5,000 lines of a Base64 encoded random log line. A log object would look something like this:<\/p>\n<pre class=\"brush:php\">{\r\n  timestamp: 'some UTC timestamp',\r\n  service: 'app',\r\n  payload: 'A base64 decoded string'\r\n}<\/pre>\n<p>The first intention is probably to go the route we did with Vue by rendering every object line in a loop. That\u2019s pretty much how it should have worked, but Angular was unperformant doing this.<\/p>\n<h4>The problem<\/h4>\n<p>The implemented way was to prerender the HTML as a string on the server and pass it down to the client. The client would then use plain JS to attach that string to the DOM. That approach brought the fastest results.<\/p>\n<p>But as soon we got close to around 8,000 lines, Angular regularly froze the browser tab, especially on slower clients. After investigating, it turned out that Angular\u2019s need for keeping track of inner scope was killing it. Eight thousand lines of log output generated 32,000 DOM nodes. Angular could not process all of those as easily as we had hoped.<\/p>\n<h4>The first solution<\/h4>\n<p>The way we made it work to give Angular the necessary \u201cbreathing room\u201d was a custom worker. That worker transformed the string into DOM nodes straight away but only injected 200 lines every 40 ms into the view. This worked fine, and Angular was then able to process up to 15,000 lines of log. However, at this level, the performance of the browser went down. Scrolling became slow.<\/p>\n<p>Obviously, this still wasn\u2019t good enough \u2014 we had clients that had even larger logs. Also we moved a lot of work to the server. Base64 decoding and pre-rendering was all done outside of the client side code.<\/p>\n<p>To get a rough understanding of efficency in rendering, I tested the 5,000 log lines in the old UI and the first Vue implementation. The only difference here was that Vue missed the worker and the log was directly dumped into the View.<\/p>\n<table border=\"1\">\n<thead>\n<tr>\n<th>Tech<\/th>\n<th>Processes<\/th>\n<th>Rendering<\/th>\n<th>Total<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Angular<\/td>\n<td>270<\/td>\n<td>6.000<\/td>\n<td>6.270<\/td>\n<\/tr>\n<tr>\n<td>Vue<\/td>\n<td>120<\/td>\n<td>2.000<\/td>\n<td>2.120<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<ul>\n<li><em>Times in ms<\/em><\/li>\n<li><em>Processes are tasks done by the code outside of the log rendering<\/em><\/li>\n<\/ul>\n<p>Just by switching the tool, we already cut the time more than in half.<\/p>\n<h4>The final solution<\/h4>\n<p>In the next iteration, I wanted to fully leverage client-side rendering of the log lines. The plain objects should get passed down, with the payload still Base64 encoded. The loop for rendering the log lines was now as simple as one might guess.<\/p>\n<pre class=\"brush:html\">html\r\n&lt;div class=\"logLine\" v-for=\"line in log\"&gt;\r\n&lt;span&gt; {{ line.timestamp }} &lt;\/span&gt;\r\n&lt;span&gt; {{ line.service }} &lt;\/span&gt;\r\n&lt;span&gt; {{ line.payload }} &lt;\/span&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>Before printing out the log, I had to decode it. For this, I created a simple JS class with functions. Vue did not force me to do things in any certain or complicated way. The code looks something like this minus the Ajax parts:<\/p>\n<pre class=\"brush:php\">\/\/ The class is written in ES6\r\nclass LogHelper {\r\n\r\n  getLog () {\r\n    \/\/ ... function that gets the log from the server\r\n    \/\/ eventually we have the raw log available for further use\r\n    let rawLog = [...]\r\n\r\n    return _prepareLog(rawLog)\r\n  }\r\n\r\n  _prepareLog (arr) {\r\n    let decodedLog = arr.map( (line) =&gt; {\r\n      line.payload = this._decode(line.payload)\r\n      return Object.freeze(line)\r\n    })\r\n\r\n    return decodedLog\r\n  }\r\n\r\n  _decode (str) {\r\n    \/\/ This correctly preserves UTF8 characters\r\n    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {\r\n      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)\r\n    }).join(''))\r\n  }\r\n\r\n}<\/pre>\n<p>In the end, we now have a reference to the log in our Vue instance, so the UI has access to it. I ended up using <a href=\"https:\/\/github.com\/vuejs\/vuex\">Vuex<\/a>, a state management inspired by Flux or Redux, but that\u2019s another story. As soon as the <code>log<\/code> was available for the template, Vue took care of rendering it. See the new benchmark added to the table:<\/p>\n<table border=\"1\">\n<thead>\n<tr>\n<th>Tech<\/th>\n<th>Processes<\/th>\n<th>Rendering<\/th>\n<th>Total<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Angular<\/td>\n<td>270<\/td>\n<td>6.000<\/td>\n<td>6.270<\/td>\n<\/tr>\n<tr>\n<td>Vue<\/td>\n<td>120<\/td>\n<td>2.000<\/td>\n<td>2.120<\/td>\n<\/tr>\n<tr>\n<td>Vue (Objects)<\/td>\n<td>1.900<\/td>\n<td>1.700<\/td>\n<td>3.600<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Those numbers were pretty interesting to me for various reasons. Let\u2019s break it down real quick:<\/p>\n<h4>Angular versus Vue (Objects)<\/h4>\n<p>The significant detail here is that the total process time is still almost 50 percent faster. But besides cutting the time in half, we also freed up process time on the server. We now Base64 decode on the client and don\u2019t need to pre-render an HTML string. This also makes the payload we need to initially load from the server smaller. Clean win!<\/p>\n<h4>Vue versus Vue (Objects)<\/h4>\n<p>One of the biggest questions is probably why the general process\u2019 time is so much bigger. The reason for this is that Vue pre-renders all the objects in the Virtual DOM of the browser. In correlation, the actual rendering time is even 300ms faster than in the previous Vue implementation.<\/p>\n<p>The Virtual DOM starts shining when it comes to the point of filtering log lines. Every object-connected DOM element is already cached and can be re-rendered instantly. That\u2019s a cost I was willing to take.<\/p>\n<h2>Why Vue Could Work for You<\/h2>\n<p>There is no such thing as the perfect tool for every job, but there is a right tool for a particular job. Vue is a tool I found to be very helpful and efficient. It only tries to be very good at one thing and nails it: bringing data into the view of your web application is a breeze as we\u2019ve seen in this article. What\u2019s even more appealing about Vue is the fact that it can grow into something more when needed.<\/p>\n<p>These days, Vue comes with a great ecosystem already.<\/p>\n<ul>\n<li>Routing? Vue-Router is available.<\/li>\n<li>Ajax Resources? Vue-resource takes care of this.<\/li>\n<li>Application State Management? Vuex is ready.<\/li>\n<li>Webpack or Browserify? Vue has the tools already prepared.<\/li>\n<\/ul>\n<p>Vue has a thriving community, a lot of stars on GitHub (21,000 versus 13,000 for Angular) and a great maintainer I fully trust.<\/p>\n<p>Please let me know what you think about Vue in the comments below, and I hope this article at least sparked your interest in considering Vue for your next project.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/consider-vuejs-next-web-project\/\">Consider VueJS for Your Next Web Project<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Roman Kuba at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for our Docker-builds UI, Jet. What Is VueJS? To get a rough idea of what Vue (pronounced \u201cview\u201d) does, think about it as the \u2018V\u2019 in an &hellip;<\/p>\n","protected":false},"author":173,"featured_media":920,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[378],"class_list":["post-13844","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","tag-vuejs"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Consider VueJS for Your Next Web Project - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Consider VueJS for Your Next Web Project - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-07-06T09:15:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Roman Kuba\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@codebryo\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Roman Kuba\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\"},\"author\":{\"name\":\"Roman Kuba\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/6312f1247141e70294400886e0719cc3\"},\"headline\":\"Consider VueJS for Your Next Web Project\",\"datePublished\":\"2016-07-06T09:15:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\"},\"wordCount\":2205,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"keywords\":[\"VueJS\"],\"articleSection\":[\"JavaScript\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\",\"name\":\"Consider VueJS for Your Next Web Project - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"datePublished\":\"2016-07-06T09:15:25+00:00\",\"description\":\"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Consider VueJS for Your Next Web Project\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/6312f1247141e70294400886e0719cc3\",\"name\":\"Roman Kuba\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/19e6195e92bd0245bcfee78b363370a3545b0650d2ed7ff294453adad05ee48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/19e6195e92bd0245bcfee78b363370a3545b0650d2ed7ff294453adad05ee48a?s=96&d=mm&r=g\",\"caption\":\"Roman Kuba\"},\"description\":\"Roman Kuba is the main front-end scientist at Codeship. Besides working with various technologies, he loves to talk about tech while teaching or at meetups. In his free time, Roman loves to spend time with his family (Dad since April 2016) and walk their dog Murphy.\",\"sameAs\":[\"https:\/\/x.com\/codebryo\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/roman-kuba\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Consider VueJS for Your Next Web Project - Web Code Geeks - 2026","description":"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/","og_locale":"en_US","og_type":"article","og_title":"Consider VueJS for Your Next Web Project - Web Code Geeks - 2026","og_description":"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for","og_url":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2016-07-06T09:15:25+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","type":"image\/jpeg"}],"author":"Roman Kuba","twitter_card":"summary_large_image","twitter_creator":"@codebryo","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Roman Kuba","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/"},"author":{"name":"Roman Kuba","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/6312f1247141e70294400886e0719cc3"},"headline":"Consider VueJS for Your Next Web Project","datePublished":"2016-07-06T09:15:25+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/"},"wordCount":2205,"commentCount":1,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","keywords":["VueJS"],"articleSection":["JavaScript"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/","url":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/","name":"Consider VueJS for Your Next Web Project - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","datePublished":"2016-07-06T09:15:25+00:00","description":"Whether or not you\u2019ve ever heard of VueJS before, never fear. I\u2019m here to share some insights on how and why we at Codeship used this \u201cnew\u201d library for","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/javascript\/consider-vuejs-next-web-project\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JavaScript","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/"},{"@type":"ListItem","position":3,"name":"Consider VueJS for Your Next Web Project"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/6312f1247141e70294400886e0719cc3","name":"Roman Kuba","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/19e6195e92bd0245bcfee78b363370a3545b0650d2ed7ff294453adad05ee48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/19e6195e92bd0245bcfee78b363370a3545b0650d2ed7ff294453adad05ee48a?s=96&d=mm&r=g","caption":"Roman Kuba"},"description":"Roman Kuba is the main front-end scientist at Codeship. Besides working with various technologies, he loves to talk about tech while teaching or at meetups. In his free time, Roman loves to spend time with his family (Dad since April 2016) and walk their dog Murphy.","sameAs":["https:\/\/x.com\/codebryo"],"url":"https:\/\/www.webcodegeeks.com\/author\/roman-kuba\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/13844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/173"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=13844"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/13844\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/920"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=13844"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=13844"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=13844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}