7

I just make it quick: In normal loading of a component (for example "Picker" component from emoji-mart-vue package) this syntax should be used:

import {Picker} from "./emoji-mart-vue";

Vue.component("picker", Picker);

And it works just fine. But when I try to lazy load this component I'm not sure exactly what code to write. Note that the following syntax which is written in the documentation doesn't work in this case as expected:

let Picker = ()=>import("./emoji-mart-vue");
1

2 Answers 2

4

The problem, I'm assuming, is that you're using

let Picker = ()=>import("./emoji-mart-vue");
Vue.component("picker", Picker);

to be clear, you're defining the component directly before the promise is resolved, so the component is assigned a promise, rather than a resolved component.

The solution is not clear and depends on "what are you trying to accomplish"

One possible solution:

import("./emoji-mart-vue")
  .then(Picker=> {
    Vue.component("picker", Picker);
    // other vue stuff
  });

This will (block) wait until the component is loaded before loading rest of the application. IMHO, this defeats the purpose of code-spliting, since the application overall load time is likely worse.

Another option

is to load it on the component that needs it.

so you could put this into the .vue sfc that uses it:

export default {
  components: {
    Picker: () => import("./emoji-mart-vue")
  }
};

But this would make it so that all components that use it need to have this added, however, this may have benefits in code-splitting, since it will load only when needed the 1st time, so if user lands on a route that doesn't require it, the load time will be faster.

A witty way to solve it

can be done by using a placeholder component while the other one loads

const Picker= () => ({
  component: import("./emoji-mart-vue"),
  loading: SomeLoadingComponent
});
Vue.component("picker", Picker);

or if you don't want to load another component (SomeLoadingComponent), you can pass a template like this

const Picker= () => ({
  component: import("./emoji-mart-vue"),
  loading: {template:`<h1>LOADING</h1>`},
});
Vue.component("picker", Picker);
Sign up to request clarification or add additional context in comments.

1 Comment

the problem with the first solution is that it always loads the module unless we use it in the components that needs it. In that case another problem rise up : the first time the component mounts up, it doesn't recognize the loaded picker component because it loads after the mounting (even if we have put this code in the beforeCreate hook method) ... overaly it can be practical work around but I wish I could handle it in the bootstrap section of the app
0

In PluginPicker.vue you do this:

<template>
  <picker />
</template>

<script>
  import { Picker } from "./emoji-mart-vue";
  export default {
    components: { Picker }
  }
</script>

And in comp where you like to lazy load do this: The component will not be loaded until it is required in the DOM, which is as soon as the v-if value changes to true.

<template>
  <div>
    <plugin-picker v-if="compLoaded" />
  </div>
</template>

<script>
const PluginPicker = () => import('./PluginPicker.vue')
export default {
  data() = { return { compLoaded: false }}
  components: { PluginPicker }
}

// Another syntax
export default {
  components: {
    PluginPicker: () => import('./PluginPicker.vue')
  }
}
</script>

1 Comment

good idea but how should I pass all of the props to through the PluginPicker to the main picker component ? It's like 30 or 40 props and multiple custom events

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.