vue-route How to create routes programmaticaly? - vue.js

I have a folder that contains several page components, like:
- pages
+ page-A
+ page-a.vue
+ page-B
+ page-b.vue
As far as I understand, if we want to render page-a.vue and page-b.vue as its own page, we must use vue-router which is described by:
import Vue from 'vue';
import Router from 'vue-router';
import PageA from '#/pages/page-A/page-a';
import PageB from '#/pages/page-B/page-b';
// ... more import for each page here ....
Vue.use(Router);
export default new Router({
routes: [
{
path: '/page-a',
name: 'PageA',
component: PageA,
},
{
path: '/page-b',
name: 'PageB',
component: PageB,
},
// ....
],
});
I had to write import for each page that I have, and also adding it to the routes, which I find as a tedious job.
Is it possible to rewrite that down to one route like: /:page which content then can be interpreted as a variable page. At least that's what I do in Express/Node server:
app.get('/:parent/:folder/:filename', function (req, res) {
var parent = req.params.parent;
var folder = req.params.folder;
var filename = req.params.filename;
res.render(parent + '/' + folder + "/" + filename);
});

Vue does accept and handle routes which can contain parameters.
Your question is about async components loading check here for more
And it's possible check this github issue: https://github.com/vuejs/vue-router/issues/215

Related

VUE: How to configure dynamical router URLs

it's my first time using Vue and I need to set a vue app on an existing and working webpage, using a relative path like https://www.my-website.tld/lang/en/xxxxxxx or https://www.my-website.tld/xxxxxxx
(xxxxxxx is a dynamical uri)
My router will be like that:
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "sesiones",
component: () => import("../views/SessionsList.vue")
},
{
path: "/session/:id",
name: "sessionid",
component: () => import("../views/SessionId.vue"),
}
],
});
export default router;
I need to know how can I generate the router (or vite.config.ts file) to make it possible.
The end result should be something like this:
If I access https://www.my-website.tld/lang/en/xxxxxxx it shows me the content of the router "/".
If I access https://www.my-website.tld/lang/en/xxxxxxx/session/24 it shows me the content of the router /session/:id
Any one can help me? Is that possible?
I tryed with path, alias, base_url in config file
I think is solved.
I set the variable base: './' to the vite.config.ts and then, changed the path to the routes like that:
First one:
path: "/:booking"
Second one:
path: "/:booking/:id"

show custom page during building process in vue js

i want to show a custom html page while building my vue js project (npm run build)
as you know while building process dist folder not exists and after build process we have dist folder .
how can i show a custom page until build is completely done?
i found this answer in a forum but how can i use that?
i dont think this is proper way!
axios.interceptors.response.use(function (response) {
if ( response.status === 503 ) {
return to maintenance page
}
return response;
});
Hi can you explain what do you want to achieve. It seems you are using VUE version that is lower than VUE CLI 3. If you want a custom page (error page, static page, 404 page, redirection page and etc.) you can still use vue router. Adding a page after a build is not a good idea since there is no route for that when you already build your project. Install vue router, create a router file or if you already have router add this.
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import PageNotFound from '#/views/pages/NotFoundPage'
import 404Page from '#/views/pages/404Page.vue'
import StaticPage from '#/views/pages/StaticPage'
const router = new Router({
routes: [
{
path: '/static',
name: 'Static Page',
component: StaticPage
},
{
path: '/404',
name: '404 Page',
component: 404Page
},
{
path: '*',
name: 'PageNotFound',
component: PageNotFound
}
]
})
export default router
You just need to redirect the user using these from your view files
this.$router.push('/static')
this.$router.push('/404')
if there are no matching route the user will automatically redirected to Page Not Found page

Dynamically choose compontent in Nuxt Router

I would like to render the same component for all languages. The translation will be done inside the component. The url and component relationship should look like so:
pseudocode:
browserurl: "/blogpost_1"
nuxtcomponent: "blogpost_1"
browserurl: "/en/blogpost_1"
nuxtcomponent: "blogpost_1"
browserurl: "/randompage"
nuxtcomponent: "randompage"
browserurl: "/en/randompage"
nuxtcomponent: "randompage"
My approach was to do the following, unfortunately i cant find a way to access pathMatch.
router: {
extendRoutes(routes, resolve){
routes.push({
path: 'en/*',
component: resolve(__dirname, '/' + somehow.access.pathMatch )
})
}
}
I don't think you can resolve component dynamically. component: expects component instance or Promise. Once the promise resolves, result is cached. I can imagine solution using navigation guards and switching components "by hand" but that would require to import views by hand etc.
So your best bet is to rewrite paths generated by nuxt to include optional path segment (from /about to /:lang(en|jp)?/about so it accepts paths like /en/about) - your component then receives lang parameter which will be empty for /about otherwise it will contain language....
Define available translations in meta
Rewrite the paths of pages with translations
In your page:
<script>
export default {
meta: {
translations: ['en', 'jp']
}
}
</script>
In Nuxt config (pseudo - not tested)
router: {
extendRoutes(routes, resolve) {
const routesWithTranslation = routes.filter(i => i.meta.translations && i.meta.translations.length > 0);
routesWithTranslation.forEach(route => {
const segment = `/:lang(${route.meta.translations.join("|")})?`
route.path = segment + route.path
})
}

Vue.JS - Both 'history' and 'hash' router?

I'm working on a Vue.Js site and using the Vue-router default mode "hash". So the site URL is something like that:
www.mysite.com/#/Home
This site is already being linked by some mobile apps, and I can't change them. But I have a new requirement and I need to change the URLs to remove the hash (#) from the URL. So I changed the Vue-router mode to "history" and now my site is working without the hash. Like that:
www.mysite.com/Home
The problem is that using the history mode the URL with the hash (#) doesn't work. But for compatibility with the mobile apps that link the site with hash, I still need to make the URL with the hash works.
QUESTION:
How can I use the Vue-router history mode and also keep the URLs with hash working?
I tried the following way at the router/index.js file:
export default new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home1',
component: Home
},
{
path: '/#/Home',
name: 'Home2',
component: Home
},
...
]})
Using this configuration the URL www.mysite.com/Home works, but the URL www.mysite.com/#/Home doesn't work.
I'm answering my own question based on the comment of the #Ohgodwhy and a question/answer from the vue.js forum that was answered by #nathany.
The solution is to remove the has (#) from the URLs that have the hash, and redirecting it to the URL without the hash. It can be done at the method router.beforeEach().
My router/index.js was something like that:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
export default new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home',
component: Home
},
],
})
Then I changed to:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
var router = new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home',
component: Home
},
],
})
export default router;
router.beforeEach((to, from, next) => {
// Redirect if fullPath begins with a hash (ignore hashes later in path)
if (to.fullPath.substr(0,2) === "/#") {
const path = to.fullPath.substr(2);
next(path);
return;
}
next();
});
For me I just needed to route external legacy links to current history-mode.
In App.vue mounted:
if (location.hash) {
location.replace(location.hash.replace('#', ''))
}
If you stumble across this...
The currently accepted answer works... But if you have a id link in the root path (for example, /#learn-more), the router redirects to /learn-more and would return a 404.
So, I modified the beforeEach route guard to:
router.beforeEach((to, _from, next) => {
if (to.hash.startsWith('#/')) {
const path = to.fullPath.substring(2);
next(path);
return;
}
next();
});
Why? In hash mode, links are passed as hashes
// console.log(to)
{
fullPath: "/#/contact",
path: "/",
hash: "#/contact",
...
}
...while normal id links (in history mode) give
{
fullPath: "/about#learn-more",
hash: "#learn-more",
path: "/about",
...
}
Looking at hash, the difference between a link to an id and a hash-mode link is #/

Router Link not loading Component

I'm trying to send a Param via the URL and the app is not loading the component
I have my link looking like
<td><router-link :to="'/ledger/detail/' + Ledger.sequence"><samp>{{Ledger.sequence}}</samp></router-link></td>
My router looks like so
import LedgerDetail from './views/LedgerDetails/LedgerDetail.vue';
{
path: "ledger/detail/:ledgerId",
name:"ledger",
component: LedgerDetail,
props: true
}
and the URL has the id appended but it's not loading the component in
I believe you need the leading slash in your path.
{
path: "/ledger/detail/:ledgerId",
//...
}