0
votes

I'm doing a project with ElementUI Tabs (just HTML and JS files, no .vue files) and I want to open a new Tab, and add html inside, like I've always used to do in Jquery and SemanticUI, for example, the user clicks the menu called "Person" and the Person View (a Vue component) opens in the tab (id = "tab1") to add a new person register, and if the user clicks again the "Person" menu, another tab opens (id = "tab2") with the Person View.

First Question: Because the Vue Component has no "el:" selector, how can I tell to component (Person View) to open inside the "tab1", and another click to open inside the "tab2" ? There is any selector like "el" in Vue.component()?

Second Question: Using Vue instance ( new Vue ({options}) ), it works, because is possible to use the selector "el", but I've read before in some blogs, that is not good practice, because the app must have only one instance of Vue. Is correct add more than one Vue instance ( new Vue () ) as used to be done adding many Vue.component ({}) in the project?

Third Question: I've read before that Vue.component() is a Vue instance, and so would be correct to say that Vue.component() and Vue() is the same thing, but with different sintax ?

2

2 Answers

0
votes

Question 1: Actually, a component does have an el. Your template determines what el is. For example, I created an inline template for my select2 that look like this:

<select2>
    <select></select>
</select2>

Vue.componet("select2", {blah blah blah});

in this case el is the select box directly.

If I did:

<select2>
    <div>
        <select></select>
    </div>
</select2>

the component el would be the div.

Question 2: what you heard from those blogs is nonsense, at least as far as Vue 2 is concerned (never worked with ver 1) You, as a coder, determine what el is in your code so it is safe to use as a selector. I do it all of the time.

Vues cannot overlap but you can have as many on a page as makes sense. On one set of my tabs, each tab is completely different from each other and independent of each other so each has its own Vue instance. On another, each tab is the same so a made a single component and generated it inside each tab as part of the parent Vue instance.

question 3: Think of Components as parts and the Vue instance as the whole containing the parts. I personally use components to reduce and compartmentalize code. For example, I have a DataTables component, a select2 component and a tab component, in all cases I have a number of each on each page. Then all I need to do is include them in my Vue instance definition.

0
votes

After almost two weeks trying, I got it ! First i created an object that has a component structure in a JS file (personview.js) that i load with requireJS, and pass as a parameter to a method of Vue Instance called appVue:

appVue.addComponent(componentName,{name:"personview",template:"<div>html tags...</div>",methods:...});

In appVue i added the method:

var appVue=new Vue({
    el:'#app',
    data() {
        return {
            components: {},
            instances: {}
        }
    },
    methods: {
        addComponent(componentName,componentBody){
            this.$data.components[componentName]=Vue.component(componentName,Vue.extend(componentBody));
        }
    }
}

When the user clicks on menu, the method openViewByClickOnMenu is called and executes:

methods: {
    openViewByClickOnMenu(){
        //id to identify the components and scripts to load     
        var componentName="personView";  //for this example i forced the name       
        //call a method that adds the new tab, and inside the tab adds 
        //<div id="divX"></div> and return the counter ever increased. 
        //X in id attribute is the number genereate by the counter
        var ctTab=body.addTab({label:menuItem.label});      
        // will be used to identify an instance of compoment
        var componentId=componentName+ctTab;  //will be personView1, personView2, etc..
        // will be used to identify the div where i want to show component
        var divTabId="div"+ctTab;
        //load the personview.js with component body
        requirejs([componentName],function(){
            //creates a new instance of component
            app.$data.instances[componentId]=new app.$data.componentes[componentName];
            //mounts the component in the div that i want
            app.$data.instances[componentId].$mount("#"+divTabId);
        });
    }

I think the Vue team could add a method in Vue instance to add components dinamically more easily, sometimes there's no need to load all html and js files because the user has no acess/permissions to see some views. And i miss a way to load html native, like Angular does, because sometimes we need generate html from template engine inside a SpringBoot for example.