Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use for loop to create async Vue component

Tags:

webpack

vue.js

My src folder looks like the following tree and the reproduction can be found at https://github.com/vwxyzjn/loop_async_import

|   App.vue
|   main.js
|
+---assets
|       logo.png
|
+---components
|   |   Hello.vue
|   |
|   \---blogpost
|           post0.vue
|           post1.vue
|           post2.vue
|
\---router
        index.js

So I am trying to create an array (blog_post_components) of asynchronous vue components (post0.vue, post1.vue, post2.vue) so that I can use them later. But if I use the for loop to create blog_post_components, the compiled website will have an error. On the other hand, if I just simply list all of them, the website is working as intended.

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '../components/Hello'

var blog_post_components = []

// THIS IS NOT WORKING AS INTENDED
// Error information: (unknown) Error: Cannot find module './post3'.

for (var i = 0; i < 3; i++){
  blog_post_components.push(() => ({
    component: import('../components/blogpost/post' + i)
  }))
}


// THIS IS WORKING AS INTENDED, ALMOST THE SAME AS THE FOR LOOP ABOVE

// blog_post_components.push(() => ({
//   component: import('../components/blogpost/post' + 0)
// }))
// blog_post_components.push(() => ({
//   component: import('../components/blogpost/post' + 1)
// }))
// blog_post_components.push(() => ({
//   component: import('../components/blogpost/post' + 2)
// })



console.log(blog_post_components)

var routes = [
  {path: '/', component: Hello}
]
for (var j = 0; j < 3; j++){
  routes.push({path: '/post/' + j, component: blog_post_components[j]})
}
console.log(routes)

Vue.use(Router)
export default new Router({
  mode: 'history',
  base: __dirname,
  routes: routes
})

Why doesn't this code work? I will really appreciate an answer.

// THIS IS NOT WORKING AS INTENDED

for (var i = 0; i < 2; i++){
  blog_post_components.push(() => ({
    component: import('../components/blogpost/post' + i)
  }))
}
like image 915
Costa Huang Avatar asked Feb 09 '26 15:02

Costa Huang


1 Answers

import is an asynchronous operation. You are likely requesting ../components/blogpost/post3 three times because var i is hoisted to the top of the scope and when the function actually executes, i == 3. Try changing your loop to use let so that i is scoped to the inside of the loop.

for (let i = 0; i < 2; i++){
  blog_post_components.push(() => ({
    component: import('../components/blogpost/post' + i)
  }))
}
like image 198
Bert Avatar answered Feb 12 '26 14:02

Bert