Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
14
rated 0 times [  18] [ 4]  / answers: 1 / hits: 16629  / 7 Years ago, fri, may 5, 2017, 12:00:00

I have a single file component Main.Vue.



I also have three other single file components A.vue, B.vue and C.vue.



I want to be able to show inside Main.Vue a different component each time. What I did was this:



<template>
<div>
<a v-if=isAVisible ></a>
<b v-if=isBVisible ></a>
</div>
</template>

<script>
import A from './A.vue';
import B from './B.vue';
...


This works but not exactly what I wanted. I wanted a different file Factory.js, which does the importing of all the components A,B,C,.. And has functions that return my component, which I can use somehow in Main.vue. Here's what I tried Factory.js to look like:



import A from './A.vue';
import B from './B.vue';
function getComponent(){
if (..)
return new A();
else if (..)
return new B();
...
}


This didn't work at all.
I want the factory file approach because:



1) I want to split it to different factory files



2) I want to Attach data to each component. So I'll have an object that contains the function returning the actual component + some additional data like name



Any ideas how to do this?


More From » vue.js

 Answers
32

Use Vue's Dynamic Components


You could use Dynamic Components to dynamically switch between components. You will need to bind the component definition object to the is attribute of the component element – Vue's documentation on this is pretty self explanatory. Below is also a brief example:


<template>
<component :is="activeComponent"></component>
</template>

import componentA from 'component/a';
import componentB from 'component/b';

export default {
components: {
componentA,
componentB,
},

data() {
return {
activeComponent: 'componentA',
},
},
};

You could directly bind the component definition object to the data property itself:


import componentA from 'component/a';
import componentB from 'component/b';

export default {
data() {
return {
activeComponent: componentA,
};
},
};

To switch out components you can programmatically change the value of activeComponent.


Use a render function


A more powerful way of dynamically mounting components can be achieved using component render functions. To do this we must create our own version of Vue's component element – we'll call this the ElementProxy:


import componentA from 'component/a';
import componentB from 'component/b';

export default {
components: {
componentA,
componentB,
},

props: {
type: {
type: String,
required: true,
},
props: {
type: Object,
default: () => ({}),
},
},

render(createElement) {
const { props: attrs } = this;
return createElement(element, { attrs });
},
};

You can now use the ElementProxy to proxy elements. The additional benefit of this is that you can pass props in as an object which will solve the problem of passing props to dynamic components with differing models.


<template>
<element-proxy :type="activeComponent" :props="props"></element-proxy>
</template>

import ElementProxy from 'components/elementProxy';

export default {
components: {
ElementProxy,
},

data() {
return {
activeComponent: 'componentA',
props: { ... },
};
},
};

Further reading



[#57886] Wednesday, May 3, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckaylab

Total Points: 311
Total Questions: 120
Total Answers: 93

Location: Montenegro
Member since Thu, Jun 16, 2022
2 Years ago
;