multiple vue js instances vs components , ajax tabs multiple vue js instances vs components , ajax tabs vue.js vue.js

multiple vue js instances vs components , ajax tabs


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.


You have to use seperate Vue instances in case you don't want the vue-router..but it will cause some memory leaks some issues so to some this .. when ever you will make an ajax request when a tab is clicked you have to first destroy the current Vue instance.. then add the data to the dom

 let app =  new Vue({            el:  '#app',        })// doo other stuff    $.ajax({      // ajax settings      success: function(data){       // here you should destroy the Old Vue instance otherwise it will make issues        app.$destroy()        $('body').html(data);      }    })

I would suggest you to make a small javascript plugin..when a link is clicked it will take the url of the link perform an ajax request and serve the data to the page on every request it will fire a callback .. where you destory the old new Instance..and for some kind of loader you can use another call back before ajax request to show the page loader or something..

I have used this technique in one of my project.. i'hv made a plugin with jquery ajax...here it is...

    import $ from 'jquery';import anime from 'animejs';export let Loader = (function(window , document , undefined){    class Loader{        constructor(options = null){            this.options = Object.assign({ pageProgressBar : false , pageProgressBarDuraion: 2000 } , options);            this.functions = [];            this.xhr = null;            this.routes = this.options.routes || [];            window.addEventListener('load' , this.init.bind(this));        }                init(){            if(this.options.container)                this.$container = $(this.options.container).length ? $(this.options.container) : $(document.body)            else                            this.$container = $(document.body)                this.functions['popstate'] =  this.onPopState.bind(this);            window.addEventListener('popstate' , this.functions['popstate'] );            this.functions['handleLinks'] = this.handleLinks.bind(this);            window.addEventListener('click' , this.functions['handleLinks']);        }        pushHistory(type , url){            var state = {url : url , type : type};            window.history.pushState(state , '' , url);        }        onPopState(e){            var state = e.state;            if(state == null)                return true;            this.loadUrl(state.url)        }        handleLinks(e){            if(!e.target.matches('[ajax-link]'))                return ;            e.preventDefault();            var url = e.target.href;            var self = this;            this.loadUrl(url).then(function(){                            self.pushHistory('get' , url);            });        }        load(url)        {            let self = this;            return new Promise(function(resolve , reject){                self.loadUrl(url).then(function(){                    self.pushHistory('get' , url);                    resolve();                });                });        }        loadUrl(url){            var isError = true;            if(this.xhr)            {                isError = false;                if(this.options.onAbort)                    this.options.onAbort();                this.xhr.abort();                if(this.options.pageProgressBar)                    restartProgressBar();                this.xhr = null;            }            var route = this.getMatchingRoute(url);            if(route)            {                if(route.beforeLoad)                    route.beforeLoad();            }            if(this.beforeLoading)                this.beforeLoading();            var self = this;            return new Promise(function(resolve , reject){               self.xhr = $.ajax({                    url : url,                    type: 'get',                    cache : false,                    beforeSend (xhr){                        if(self.options.onLoading)                            self.options.onLoading(xhr);                        if(self.options.pageProgressBar)                            startProgressBar( self.options.pageProgressBarDuration );                    },                    success (data){                        self.$container.html(data);                        self.xhr = null;                        resolve();                        if(route && route.afterLoad)                            route.afterLoad();                        if(self.options.onLoaded)                            self.options.onLoaded(data);                        if(self.options.pageProgressBar)                            endProgressBar();                    },                    error (response){                        if(response.response)                            window.location = url;                    },                });            });        }        reload(){            this.loadUrl(window.location.href);        }        getMatchingRoute(url){            if(this.routes)            {                   for(let i = 0; i< this.routes.length ; i++)                {                    var route = this.routes[i];                    if(url.indexOf(route.route) >= 0 ){                        return route;                    }                };            }            return null;        }        destory(){            window.removeEventListener('popstate' , this.functions['popstate'] );        }    }    return Loader;    // Provate progressbar methods    var $pageProgressBar = null;    function restartProgressBar(){        $pageProgressBar.remove();        anime.remove($pageProgressBar[0]);    }    function startProgressBar( duration = 3000){        $pageProgressBar = $('<div>').addClass('page-progressbar')        $('body').append($pageProgressBar)        anime({            targets: $pageProgressBar[0],            width: '70%',            easing : 'easeInOutQuad',            duration : 3000        });    }    function endProgressBar(){        anime.remove($pageProgressBar[0]);        var $prog = $('.page-progressbar');        $prog.css({ width: '100%' , transition :".35s all" , 'webkit-transition' : ".35s all" });        setTimeout(()=>{            $prog.css({ opacity: '0'});            setTimeout( () => $pageProgressBar[0].remove() , 200);        },350);    }}(window , document , undefined));

it has some progress bars and other things you can remove that modify itnow all you have to do is

window.Loader = new Loader({// tell it the tag you want to put data in container :"#app-data",})

then add the ajax-link attribute to any link in your case its tabs linksit will pull the url and put the contents to the container you specfiedand there are some call backsyou can add a Loader.beforeLoading = function(){ app.$destroy(); }and thats it