Vuejs lazy loading routes in webpack template - javascript

I have created vuejs project with vue-cli tools and webpack template.
vue init webpack my-project
I don't know how to implement lazy loading on routes with templates
currently i have two routes in router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Test from '#/components/Test'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/test',
name: 'test',
component: Test
}
]
})
And its imported in main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
But it doesn't contain the lazy loading implementation how can i do it??

instead of using
import Test from '#/components/Test'
use as
const Test = () => import('#/components/Test');
lazy loading Documentataion

Nice way to do this:
function load (component) {
return () => import(`#/${component}.vue`)
}
...
routes: [
{ path: '/', component: load('Hello') },

Related

vue-router showing blank page when built

I'm asking for help. I use vuejs to make my application. Everything works perfectly. But I do the npm run build, I extract the dist folder and I open index.html, I have a blank page, and when I look in the console, I have no errors.
main.js
import Vue from "vue";
import Vuex from "vuex";
import router from "./router";
import App from "./App.vue";
import vuetify from "./plugins/vuetify";
import store from "./store";
import {
ValidationObserver,
ValidationProvider,
extend,
localize
} from "vee-validate";
import fr from "vee-validate/dist/locale/fr.json";
import * as rules from "vee-validate/dist/rules";
// install rules and localization
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
localize("fr", fr);
// Install components globally
Vue.component("ValidationObserver", ValidationObserver);
Vue.component("ValidationProvider", ValidationProvider);
Vue.config.productionTip = false;
//load vue-moment
Vue.use(require("vue-moment"));
//Load vuex
Vue.use(Vuex);
//Load vueRouter
new Vue({
router,
vuetify,
store,
render: h => h(App)
}).$mount("#app");
router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Professeur from "../components/Professeur";
import Matiere from "../components/Matiere";
import Dashboard from "../components/Dashboard";
import Filiere from "../components/Filiere";
import Salle from "../components/Salle";
import Shedule from "../components/Shedule";
import SheduleLine from "../components/SheduleLine";
import Login from "../components/Login";
import Home from "../components/Home";
Vue.config.productionTip = false;
Vue.use(VueRouter);
const router = new VueRouter({
mode: "history",
routes: [
{
path: "/dashboard",
name: "dashboard",
component: Dashboard,
meta: {
requiresAuth: true
},
children: [
{
path: "personnel/professeurs",
name: "p_professeur",
component: Professeur
},
{
path: "",
name: "home",
component: Home
}
]
},
{
path: "/login",
name: "login",
component: Login,
meta: {
guest: true
}
}
]
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
let user = JSON.parse(localStorage.getItem("_GET_TOKEN"));
if (!user && !user.token) {
next({
name: "login"
});
} else {
next();
}
} else {
next();
}
});
export default router;
App.vue
<template>
<v-app>
<router-view/>
</v-app>
</template>
<script>
export default {
name: 'app',
}
</script>
Once I compile, I have no errors but a blank page.
Thanks for any help. I tried without the router view, I manage to launch the index.html once compiled for production and I have a rendering.
You're using history mode for your router, which means you'll access your pages with paths like /login or /dashboard or /dashboard/personnel/professeurs, which are the only routes you declared.
/ or /index.html does not display anything because the router doesn't know what they are.
However, in order to have history mode working, you cannot just have a static server. The server has to know that a request to /dashboard should return the index.html file.
If you used VueCLI, the docs here might be helpful:
If you are using Vue Router in history mode, a simple static file server will fail. For example, if you used Vue Router with a route for /todos/42, the dev server has been configured to respond to localhost:3000/todos/42 properly, but a simple static server serving a production build will respond with a 404 instead.
To fix that, you will need to configure your production server to fallback to index.html for any requests that do not match a static file. The Vue Router docs provides configuration instructions for common server setups.
If you don't want to deal with this, or don't have a server enabling you to do this, you can switch history to hash mode in your router. Your routes will be accessible at /index.html#/dashboard and so on.
If you are running into this issue (as I was) in 2022 with a serverless vue 3 application and vuex, you can configure the hash-histroy like so
import { createRouter, createWebHashHistory } from 'vue-router'
import { type RouteRecordRaw } from 'vue-router'
import { Admin, Welcome } from '/#/views'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Welcome',
component: Welcome
},
{
path: '/admin',
name: 'Admin',
component: Admin
}
]
const router = createRouter({
history: createWebHashHistory(), // <--- this is important
routes
})
export { router }
See also: docs
router/index.js :
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes
})
export default router
main_folder/vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
publicPath: ''
})
Important: use publicPath: '' and createWebHashHistory
That is all. You can now build. But remember that your links will appear as /index.html#/dashboard.

Vue.js: addRoutes method with array from API call

I am going to use the addRoutes method for the first time. I didn't find any full tutorials of how developers can use this method so I decided to try and ask here.
In my app I have some sort of CMS so a user can create new pages with custom paths. In my router/index.js file where I import components and declare their routes I need to add these custom routes.
I have an API endpoint which can give me a JSON with arrays of these routes. How can I call this endpoint in my router/index.js file and add these new routes to my router?
Here is what I have in my router.index.js file (I added its structure rather than code itself):
import Vue from 'vue';
import VueRouter from 'vue-router';
import http from '../http';
import config from '../config';
import Home from '../components/pages/Home';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/home',
name: 'home',
component: Home,
},
...
],
});
router.addRoutes([]);
export default router;
You can use addRoutes in this way:
import router from '#/router'
import Project from './pages/Project'
import Projects from './pages/Projects'
router.addRoutes([{
path: '/projects',
name: 'projects.projects',
component: Projects,
props: false
}, {
path: '/projects/:id',
name: 'projects.project',
component: Project,
props: true
}])
From docs:
Dynamically add more routes to the router. The argument must be an Array using the same route config format with the routes constructor option
Full example:
You have the main router like this:
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../components/pages/Home';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/home',
name: 'home',
component: Home,
},
],
});
export default router;
Now, you create a new page with the following structure.
-- NewPage
-- NewPage.vue
-- route.js
The route.js should look like this:
import router from '#/router' //importing the main router
import NewPage from './NewPage.vue'
router.addRoutes([
{
path: '/new-page',
name: 'newPage',
component: NewPage,
},
])
Hope I helped you.

vue-router : failed to resolve async component render

I am a beginner to vue-router and I can't make it work. When I start my app, I get the following errors :
[vue-router] Failed to resolve async component render: TypeError: _vm is undefined
49:16:39
[vue-router] uncaught error during route navigation:
49:16:39
TypeError: _vm is undefined
Stack trace:
render#webpack-internal:///63:3:7
resolveAsyncComponents/</<#webpack-internal:///49:1774:17
flatMapComponents/</<#webpack-internal:///49:1801:66
...
Here are my files : main.js
import Vue from 'vue'
import App from './App.vue'
import router from './routes.js'
import 'bootstrap'
new Vue({
el: '#app',
router,
render: h => h(App)
})
routes.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './Home.vue'
export const routes = [
{ name: 'Home', path: '', components: Home }
]
Vue.use(VueRouter)
const router = new VueRouter({
routes
})
export default router
There is a typo in routes, change components to component:
export const routes = [
{ name: 'Home', path: '', component: Home }
]

How update component after click and url change?

I try use vue-router, but something went wrong.
On page rendered router-link, by click url changed. localhost/#/ -> localhost/#/contacts but component steal main page. Update only if page reload.
main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './index.vue';
import Error404 from './404.vue';
import Routes from './route';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'hash',
routes: Routes
});
window.onload = () => {
new Vue({
router: router,
el: '#app-container',
data: {
currentRoute: window.location.hash.split('#')[1]
},
computed: {
ViewComponent () {
return Routes.filter(item => item.path == this.currentRoute)[0] || Error404
}
},
render (h) { return h(this.ViewComponent.component ? this.ViewComponent.component : this.ViewComponent) }
});
}
route.js
const routes = [
{path: '/', component: mainPage},
{path: '/example1', component: examplePage},
{path: '/example2', component: exampleForm},
{path: '/contacts', component: contacts}
];
export default routes
index.vue
<template lang="jade">
div(id="app")
router-link(to="/example1") Example1
br
router-link(to="/example2") Example2
br
router-link(to="/contacts") Contacts
</template>
<script type="text/javascript">
export default {
}
</script>
I fix problem by add
watch: {
'$route'(to, from) {
this.$router.go(this.$router.currentRoute)
}
}
for main.js, but i think this is very bad solution.
you are missing router-view. this is the component responsible to render the component that the router needs to display
please consider this code structure based on official boilerplate:
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
index.vue
<template>
<div id="app">
<router-view/>
<router-link to="example1">example1</router-link>
<router-link to="example2">example2</router-link>
</div>
</template>
index.js (like your route.js)
import Vue from 'vue'
import Router from 'vue-router'
import example1 from '#/components/example.vue'
import example2 from '#/components/example2.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/example-1',
name: 'example-1',
component: example1
}
{
path: '/example-2',
name: 'example-2',
component: example2
}
]
})

[Vue warn]: Error in render function: "TypeError: Cannot read property 'matched' of undefined" [duplicate]

This question already has answers here:
Vue-router error: TypeError: Cannot read property 'matched' of undefined
(7 answers)
Closed 4 years ago.
am trying to route using two routers for two pages,
main.js and profile.js
and
two init files main and profile
//for main pages
import Vue from 'vue';
import App from './App';
import MainRouter from './router/main.js';
Vue.config.productionTip = false
/* eslint-disable no-new */
/* vue init for main pages with MainRouter */
new Vue({
el: '#main-app',
MainRouter,
template: '<App/>',
components: {
App
}
})
import Vue from 'vue';
import App from './App';
import ProfileRouter from './router/profile.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
/* vue init for profile pages with profile pages router */
new Vue({
el: '#profile-app',
ProfileRouter,
template: '<App/>',
components: {
App
}
})
routers are..
/* Router for main pages */
import Vue from 'vue'
import Router from 'vue-router'
/* pages */
import Meeting from '#/components/pages/meeting'
import Feeds from '#/components/pages/feeds'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Feeds',
component: Feeds
},
{
path: '/meeting',
name: 'Meeting',
component: Meeting
},
{
path: '/activities',
name: 'Activities History',
component: Activities
},
{
path: '/add_member',
name: 'Add Member',
component: Add_Member
}
]
})
profile.js
/* Router for profile related pages */
import Vue from 'vue'
import Router from 'vue-router'
/* pages */
import Activities from '#/components/pages/activities_history'
import Change_Password from '#/components/pages/change_password'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Edit Profile',
component: Edit_Profile
},
{
path: '/activities',
name: 'Activities History',
component: Activities
}
]
})
ill include more codes if needed...
it was working fine while there was only one router.
can u troubleshoot issue.
Thanks in advance
When you add the router to your Vues you must use the name router.
new Vue({
el: '#main-app',
router: MainRouter,
template: '<App/>',
components: {
App
}
})
new Vue({
el: '#profile-app',
router: ProfileRouter,
template: '<App/>',
components: {
App
}
})
Vue has no idea what a ProfileRouter or a MainRouter are. It's important to remember that the syntax
{ router }
is shorthand for
{ router: router }
which was something that was introduced with ES2015.

Categories

Resources