3

I want to render ajax tabs using vue js. For each tab, ajax request fetches template + data from api.

so these are the tabs:

<div id="tabs">
  <ul class="nav nav-tabs">
    <li class="active"><a href="#tab1" role="tab" data-toggle="tab">Tab1</a></li>
    <li><a href="#tab2" ajax-url="/tab2" role="tab" data-toggle="tab">Tab2</a></li>
    <li><a href="#tab3" ajax-url="/tab3" role="tab" data-toggle="tab">Tab3</a></li>
    <li><a href="#tab4" ajax-url="/tab4" role="tab" data-toggle="tab">Tab4</a></li>
  </ul>

  <div class="tab-content">
    <div role="tabpanel" class="tab-pane active" id="tab1"></div>
    <div role="tabpanel" class="tab-pane" id="tab2"></div>
    <div role="tabpanel" class="tab-pane" id="tab3"></div>
    <div role="tabpanel" class="tab-pane" id="tab4"></div>
  </div>
</div>

<script>
$('#tabs').on('shown.bs.tab', function (event) {
   var url = event.target.getAttribute("ajax-url");
   // fetch template and data..
   // init vue instance for the new tab
})
</script>

How should I integrate vue into this? Separate vue instances for each tab, or components? I also need support for preloading some of the tabs.
Since I need to initialize the vue instances on demand, I'm not sure what is the good way to manage that. For angular, I would define ng-controller for each tab. But in vue.js it seems there isn't one correct project architecture.

Uddhav P. Gautam
  • 7,362
  • 3
  • 47
  • 64
user3599803
  • 6,435
  • 17
  • 69
  • 130

2 Answers2

3

For the tabs, use vue-router

Each route will load a separate View/Component when active. However, this is preloaded as the vue.js bundle file contains all the code required to render.

The Vue Lifecycle hooks, such as created and mounted are commonly used to perform setup or fetching of additional data in each View.

It looks like your example is homogenous enough that a single vue instance can handle all the workings (no jQuery/AJAX required).

If your use-cases differ greatly sometimes it is more effective to build multiple separate components, each compiled into their own JS file (usually done with Webpack's multiple 'entry' setting).

UPDATE

There is a way to bundle Vue components using the CLI see: Compile .vue file into .js file without webpack or browserify

Note that each Component will be able to mount a separate tab, using el attribute which works similar to the Angular 'ng-controller' directive:

new Vue({
  el: '#tab1',
  data () {
    return {
      obj
    }
  }
})

However, I think what you're trying to do is to control Vue instances from outside of Vue (ie: using jQuery). This is probably not recommended.

If you decide to go with Webpack, you are still able to use Bootstrap. The are various ways to integrate Bootstrap, personally i would recommend importing the SCSS. However your mileage may vary. But don't be put off, there are plenty of online resources to keep you going.

  • Do I have to use a component for each tab? For this project I can't use webpack or other builders. I prefer to integrate vue.js incrementally, so I can't ditch jQuery yet. I need jQuery for bootstrap. What I want is to load a template + data for each tab. vue-router looks somewhat complicated and most of the docs assume that I use webpack/bundler – user3599803 Feb 27 '18 at 15:50
  • See my update for the answer to this question. What have you tried so far? – Sebastian Scholle Mar 09 '18 at 13:20
  • the CLI is also not an option for me, as I've said I don't use a builder like webpack and that include vue cli. Tried the vue router but it seems too overloaded for my purpose (I don't need hashbangs, links state management, just load ajax tab on click). I tried to define my tabs on JS code like vue router does, and then use v-for on the
  • elements. But is there any way to define the tabs in HTML like bootstrap requires?
  • – user3599803 Mar 09 '18 at 14:42