Undefined Rants

Code, Ramen and Avocado

Vue.js Server Side Rendered Data

Currently I had been using Vue.js in work and hobby so I would like to share something I learnt.

Note: Examples are tested in Vue.js 1.0

When you start your Vue.js application, the first thing you do is probably getting data from your backend or api. Let’s say we have a list of comments from our backend server.

1
2
3
4
5
6
7
8
new App({
  created() {
    fetch('/comments')  // using ajax etc
    .done(function(res) {
      this.comments = res.comments;
    }.bind(this));
  }
})

This is how our app flow looks like:

1
  html from server get rendered -> request data through ajax -> render data via Vue.js

Doing this is totally fine but we can reduce this http request. Making our app flow

1
  html + data from server (get rendered and injected) -> render data via Vue.js

We can reduced a http request when initialize our application. Let’s see how we can do this via Vue.js. We can achieve these by using 2 ways, through the native HTML5 custom attribute way and through props supported by Vue.js.

1. HTML5 custom attribute

What we need to do is when our backend return rendered html root, we will insert the data as custom attribute.

1
2
3
4
// from any backend, syntax might different according to template engines
<div id='commentList' data-comments='<% $commentsFromServer %>'>
... other components here
</div>

Here is how you do it in PHP.

1
2
3
4
5
// example in PHP
// assume $comments is an array
<div id="commentList" data-comments='<?php echo json_encode($commentsFromServer, JSON_HEX_APOS); ?>'>
... other components here
</div>

Here #commentList div is our Vue.js root component.

1
2
3
4
5
6
7
new Vue({
  el: '#commentList'

  created() {
    this.comments = this.$el.dataset.comments
  }
}

And we save one http request =).

2. Vue.js props

The second approach is same but it use the props. That’s if you are not writing Vue.js application by breaking down into component you should use the first approach.

1
2
3
4
5
6
7
8
9
Vue.component('commentsList', {
 props: ['comments']  // important !!!
 template: '<div v-for="comment in comments"> ... </div>'
});

// initialize
new Vue({
  el: '#commentList'
}

Instead of injecting our data into the root this time we can inject directly.

1
2
3
<div id="commentList">
  <comments-list :comments='<% $commentsFromServer %>'></comments-list>
</div>

Recap

Initialized our data for js application through server side instead of ajax call make our app rendered faster so we can deliver our application to user asap. We discussed 2 approach to do this in Vue.js. Both are fine but I recommend the second way, which let you to write application by composing component

Comments