Mosh
Mosh

Reputation: 471

VueJS - Load separate component into vue instance

At my job I'm currently in the progress of a redesign of our web platform, including moving a lot of old javascript / jquery into VueJS.

I have a global.js file which holds our Vue components and we have a vendor.js which holds Vue, Axios, Vuex,...

Now we have a text editor on our site and this editor has a Vue version. The problem is that this text editor is pretty big, almost 500kb minified for production. So I've created a separate component in a separate file for this editor, since we only need it on two pages.

enter image description here

Now, since my global Vue takes up the whole page I cannot insert the text editor into it because you can't put a Vue instance inside another Vue instance.

Is there a way that I can keep the editor as a totally separate file but somehow use the global Vue instance when it gets loaded on a page?

I've searched for quite a bit but haven't come across this problem anywhere. Maybe it's not possible to do this.

Upvotes: 9

Views: 2589

Answers (5)

Andrew Vasylchuk
Andrew Vasylchuk

Reputation: 4779

Try loading TextEditor.vue asynchronously.

new Vue({
  // ...
  components: {
    TextEditor: () => import("./TextEditor.vue")
  }
})

Reference.

Upvotes: 3

Daniel Richter
Daniel Richter

Reputation: 358

You should take a look at splitting your bundle into chunks: https://webpack.js.org/guides/code-splitting/

Only load your text editor chunk on pages that require it.

Upvotes: 1

GenericUser
GenericUser

Reputation: 3230

You can merge multiple Vue files together through imports and the components property within a .vue file.

<template>
   <div>
      <TextEditor></TextEditor>
   </div>
</template>

<script>
import TextEditor from 'path/to/TextEditor.vue';

export default {
   name: 'Main',
   components: {
      TextEditor
   }
}
</script>

Furthermore, you can set this to be a dynamic import. If your project was set up with vue-cli, you should already have webpack installed. If that's the case then you can also set the dynamic import to have one of two types: prefetch or preload. Essentially prefetch downloads files when the app is idle and preload downloads it in parallel to the main component. Implementing either of those aspects ends up looking like this:

export default {
   name: 'Main',
   components: {
      TextEditor: import(/* webpackPrefetch: true */ 'path/to/TextEditor.vue')
      /* OR */
      // TextEditor: import(/* webpackPreload: true */ 'path/to/TextEditor.vue')
   }
}

Upvotes: 2

Nishant Arora
Nishant Arora

Reputation: 388

You can put a Vue instance inside another Vue instance.

Let's say I have the following HTML

<div id="main-app"></div>


new Vue({
  el: "#main-app",
  template: `<div>
        This is my main application which has an editor div
        <div id="editor"></div>
     </div>`
});


new Vue({
  el: "#editor",
  template: `<div>
        This is my editor component
     </div>`
});

The final resulting HTML would be

<div>
  This is my main application which has an editor div
  <div>
    This is my editor component
  </div>
</div>

Upvotes: 0

Steven Spungin
Steven Spungin

Reputation: 29071

You can modify the CSS for the editor to position:fixed or position:absolute and put it inside your app component. Then use a v-if to toggle visibility.

You can also wrap your editor using a 3rd party dialog component to wrap it into a modal popup window.


Another unrelated suggestion is to use lazy loading if the component has a large size.

Upvotes: 3

Related Questions