VUE: How to configure dynamical router URLs - vue.js

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"

Related

vueJS 3.x: navigate from page after HTML form-submit

Versions:
vueJS: 3.0.0
vuex: 4.0.2
Chrome: Version 94.0.4606.61 (Official Build) (x86_64)
One advantage of SPA frameworks like vueJS is that they offer some efficiencies in network consumption (ie, fewer server hits by delivering UI/UX assets to client in bulk, and hopefully minimizing server requests). But I'm running into a scenario where just the opposite happens: ie, I am required to revisit the server in order to navigate between vueJS components/views. This seems highly contradictory to the SPA ethos, and I'm suspicious something simple must be wrong in my setup. Details follow.
router/index.js:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '#/views/Home.vue'
import Car from '#/views/Car.vue'
import Bike from '#/views/Bike.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '#/views/About.vue')
},
{
path: '/cars/new',
name: 'New Car',
component: Car
},
{
path: '/cars/:id',
name: 'Edit Car',
component: Car,
props: true
},
{
path: '/bikes/new',
name: 'New Bike',
component: Bike
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
Then in Car.vue component, I have a form-submit handler something like this:
handleSubmit(event) {
let form = event.target;
if (form.checkValidity()) {
// Add or update Car.
window.location.href = window.location.origin + process.env['BASE_URL'];
}
this.wasValidated = true
Rather than using window.location.href, I tried to use:
this.$router.push('Home');
But that had no effect. That is, the URL in the browser address bar began as something like http://localhost:8080/myapp/, and remained that way after the router-push.
I also tried pushing to other routes, like About; in that case, the browser address bar properly toggled to http://localhost:8080/myapp/about, but the page content remained the same!
Clearly, this cannot be the right behavior.
Can you suggest how to fix this?
this.$router.push('Home') tries to push 'Home' as a path, but there's no matching path in your router config, nor is there a fallback route (for 404s), so the route simply doesn't change.
If you meant to push the route by name, the $router.push() argument needs to be an object:
this.$router.push({ name: 'Home' })
If you prefer to use a path, the path of Home is actually /:
this.$router.push('/')

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 #/

vue-route How to create routes programmaticaly?

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

Dynamically set base in vue-router

I am trying to dynamically pass in data to set the base for vue-router. Is it possible to setup a separate function elsewhere that passes in a base name variable? For example, if an editor wanted to set the base name via a CMS, I’d want a way to pass (or import) that name through.
// router/index.js
export default new VueRouter({
base: '[PASS BASE NAME HERE]',
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/contact',
name: 'Contact',
component: Contact
}
],
mode: 'history'
})
I ended up setting a variable on my index.html and importing it to the router. This can also be done by importing a variable from a module js file, but setting it on the html seems to avoid build issues. Simpler solution than I thought, thanks #lamelemon.
// index.html
var serializedModel = #Html.Raw(Model.Serialized());
// router/index.js
var baseUrl = serializedModel.BaseUrl;
export default new VueRouter({
base: baseUrl,
mode: 'history',
routes: [{...}]
})

Vue-router will not load the correct component

Using vue-router, it keeps throwing me back to the initial component I have routed to /
Router is initialized as such:
export default new Router({
history: true,
routes: [
{
path: '/',
name: 'BodyParent',
component: BodyParent
},
{
path: '/configuration',
name: 'Configuration',
component: Configuration
}
]
})
If I go to /configuration, it will still load the BodyParent component, but the browser URL will go to /configuration initially, then to /configuration#/ while still loading BodyParent
If I put the Configuration component to route to /, it does render it. How come?
So the problem is pretty generic - Vue router defaults to the component that is set to /
The issue was that I was using a regular href to navigate.
I should have used: <router-link to="Configuration">Config</router-link>