Search code examples
javascriptjqueryvue.jsvuejs2server-rendering

Using Vue to enhance existing Multi page / server rendered / classic web app


I’v been searching for hours now and didn’t find anything close to my use case.

  • I have a classic / multi page / server rendered e-commerce webstie made with JAVA
  • I have a page where the server renders a list of products with a pagination
  • Today, i use jQuery to do the pagination to give a better loading experience to the user
  • On my server, if the request is AJAX a send a json response, else i render a normal html view
  • With jQuery and vanilla it’s really easy, with Vue it doesn’t seem to work because Vue’s v-for and other template binding replaces the server rendered template directly…
  • The server would render this :

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

article {
  margin: 8px 0;
  background: #eee;
  padding: 20px;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<!-- server rendered -->
<div id="app">
  <h2>Freelance list</h2>
  
  <article>
    <h3>louane</h3>
    <p>
      City : <strong>courbevoie</strong>
      <br> Phone : <strong>05-36-23-51-89</strong>
    </p>
  </article>
  <article>
    <h3>indra</h3>
    <p>
      City : <strong>rheden</strong>
      <br> Phone : <strong>(354)-415-2419</strong>
    </p>
  </article>
  <article>
    <h3>angelo</h3>
    <p>
      City : <strong>montpreveyres</strong>
      <br> Phone : <strong>(883)-474-9314</strong>
    </p>
  </article>
  
  <a href="/prev-link">prev</a>
  <a href="/next-link">next</a>
</div>
<!-- server rendered -->

  • I want to be able to do something like this but with Vue :

// fake url link, normally this would be taken from the href or something
var url = 'https://randomuser.me/api/?seed=abc&results=3&page=';
var page = 1;
var $articles = $('.articles');
var tpl = $articles.children().eq(0).clone();

$('.prev').click(function(e) {
	e.preventDefault();
  
  if (page <= 1) {
  	return
  }

  page--;
  $.getJSON(url + page)
  	.done(onReqDone);
});

$('.next').click(function(e) {
	e.preventDefault();

  page++;
  $.getJSON(url + page)
  	.done(onReqDone);
});

function onReqDone(res) {
  $articles.html('');

  res.results.forEach(function(user) {
    var $node = tpl.clone();
    $node.find('h3').text(user.name.first);
    $node.find('strong:eq(0)').text(user.location.city);
    $node.find('strong:eq(1)').text(user.phone);
    $articles.append($node);
    window.scroll(0, 0);
  });

}
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

article {
  margin: 8px 0;
  background: #eee;
  padding: 20px;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- server rendered -->
<div id="app">
  <h2>Freelance list</h2>

  <div class="articles">
    <article>
      <h3>louane</h3>
      <p>
        City : <strong>courbevoie</strong>
        <br> Phone : <strong>05-36-23-51-89</strong>
      </p>
    </article>
    <article>
      <h3>indra</h3>
      <p>
        City : <strong>rheden</strong>
        <br> Phone : <strong>(354)-415-2419</strong>
      </p>
    </article>
    <article>
      <h3>angelo</h3>
      <p>
        City : <strong>montpreveyres</strong>
        <br> Phone : <strong>(883)-474-9314</strong>
      </p>
    </article>
  </div>

  <a href="/prev-link" class="prev">prev</a>
  <a href="/next-link" class="next">next</a>
</div>
<!-- server rendered -->

Any ideo on how to do it ? Here are my tries : https://jsfiddle.net/7270zft3/2/ : problem, it doesn’t remove the old dom

PS : Before anyone talks about SSR with Vue ou just doing an SPA, here’s why i cant :

  • This e-commerce website can’t be totally re made with a Single Page App, it will cost too much time and money for the benefit it would bring to us
  • This e-commerce needs SEO to continue to drive traffic, just like any e-commerce btw
  • If Vue can really be used like jQuery (this is why we bet on Vue), we should be able to do this without doing a full rewrite
  • Event if we had time to rewrite an SPA, we can’t use SSR because our backend is made with JAVA and SSR seems to only be available with node and PHP with v8js module

Solution

  • Someone on the Vue forum found a good approach close to what was posted here but suited better my need : https://forum.vuejs.org/t/using-vue-to-enhance-existing-multi-page-server-rendered-classic-web-app/30934/20