Access Router Params VueJS - javascript

I'm creating a blog using Vuejs and I'm fairly new to it.
In short. I have a dynamic list of elements that are loaded onto the screen and when you click on one of the items, I want to go to that page with the rest of the data. I followed somewhat of the same process I did if I was using React.
Router.js
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/post/:id",
name: "PostView",
props: true,
component: PostView
}
]
});
I have my router setup to take dynamic links.
Component That Creates List Data
<template>
<router-link v-bind:to="{ path: 'post/' + post.postId, params: { post } }">
<div> .... </div>
</router-link>
</template>
<script>
import moment from "moment";
export default {
name: "recentPostTile",
props: {
post: Object,
},
};
</script>
As you can see that is how I did my router-link and in my actual Page View this is how I'm trying to read the data. 2 different way's I tried to read it.
props: {
post: Object
},
AND
data() {
return {
postData: this.$route.params.post, (also tried with $route)
};
},
and when I try to console out post/postData I just get undefined. I can assure you that the data does exist since the data is hard coded into the browser.
Also I tried to pass the params as key value pairs as well and that didn't work. I also create a new variable for the data I was going to be passing through the link. That didn't work either. I also haven't tired query, just because I don't want an ugly looking link.

Change your link to:
<router-link :to="{ name: 'PostView', params: { id: post.postId, postData: post } }">
<div> .... </div>
</router-link>
The changes:
Used the name property to specify the route
Removed the hardcoded path
Passed the id param, as that is the param name given in the route definition (/:id)

Related

Vue-router keeps appending # to existing routes. P.S this isn't the typical hash, history mode issue

Using Vue 3, i have my router file set up this way
import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/Portfolio",
name: "Portfolio",
component: () =>
import(/*webpackChunkName: "DestinationDetails" */ "../views/Portfolio"),
},
{
path: "/Services",
name: "Services",
component: () =>
import(/*webpackChunkName: "DestinationDetails" */ "../views/Services"),
},
{
path: "/details/:id",
name: "PortfolioDetails",
component: () =>
import(
/*webpackChunkName: "DestinationDetails" */ "../views/PortfolioDetails"
),
},
{
path: "/:pathMatch(.*)*",
redirect: "/Home",
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
I am also running a v-for loop to get paths from an API "https://api.fake.rest/ca2a6662-22d0-4010-ba08-0440ffe813ab/menu". 3 of the 5 url paths have a value of "#". the remaining two have normal paths.
<div
v-for="(men, index) in webMenu.menu_items"
:key="index" class=" mt-32"
>
<!-- <SidebarLink class="w-full" :to="{path:men.url}" icon="fas fa-home">{{
men.name
}}</SidebarLink> -->
<router-link class="w-full" :to="men.url"> {{men.name}} </router-link>
</div>
<p class="font-bold">{{webMenu.menu_text}}</p>
</div>
Problem is now when the webpage loads initially, it works fine but after clicking on the portfolio or services link, the paths to the others are changed.
e.g if i was on the portfolio page and tried switching back to the home page, it would change the route path to "portfolio#" and refuse to switch pages.
Can anyone help explain why this is and a possible way to resolve it?
I was also facing the similar issue.
For me the issue was that I was redirecting to new page using router.push() on click of a div.
And I was using #click.stop = "myFunction" . This was adding a # in the url and not redirecting the user.
I tried different variation of this as well. I tried using event object as well like event.stopPropagation(). With this as well got same result.
When I used #click.prevent, this everything worked as expected.
PS:
You can use catch block to trace the error as well.
this.$router..push({
name: "PAthName",
params: { id },
query: { id }
})
.catch(e => {
console.log("Errors", e);
});
Should have updated this earlier.
The fix was relatively simple, all i did was change the binding from
<router-link class="w-full" :to="men.url"> {{men.name}} </router-link>
to
<router-link class="w-full" :to="`/${men.url}`"> {{men.name}} </router-link>
and voila!

Vue.js form page loses its data when coming back from a new page

I have a Vue.js page that is basically one big textarea. If the user taps "Settings" on that page and opens the Settings page, then goes back to the original page, the textarea data is all gone. Surely there must be an easy way of not losing everything without saving it to a database or something, right?
I'm using Vue Router.
Does Vue Router have something like a modal window (but for use in a smart phone app) that can be dismissed so everything underneath is saved?
I would encode the form ID in the route path, and set props=true so that the ID is passed to the component's prop:
// router.js
export default new VueRouter(
routes: [
{
path: "/form/:id",
name: "form",
component: () => import("#/components/MyForm.vue"),
props: true
}
]
)
// MyForm.vue
export default {
props: {
id: {
type: [Number, String],
default: 0,
required: true,
},
},
data() {
return {
text: "The text " + this.id,
};
},
}
Then use <keep-alive> to reuse cached views, and use the route's full path as the key for router-view:
<keep-alive>
<router-view :key="$route.fullPath" />
</keep-alive>
demo

Vue Router passing props to dynamic routes, unclear documentation

I have a ProjectCard component which, among other things, links to a specific ProjectPage component. The ProjectPage is going to have a bunch of different paragraphs, pictures and so on, not wholly relevant for my question.
How do I pass on props to a ProjectPage? The Vue Docs portion on Boolean Mode is incredibly vague and doesn't really tell me anything useful.
My Router index.js file has the prop decoupling that they mention in the docs
import ProjectPage from "#/views/ProjectPage.vue"
const routes = [
{
path: "projects/:id",
component: ProjectPage,
props: true
}
To test things out, I made the ProjectPage.vue component look like this
<template>
<div>Static text, followed by {{ testString }}</div>
</template>
<script>
export default {
name: "ProjectPage",
props: {
testString: String
}
};
</script>
And I tried passing on a test string to it from my ProjectCard component like this:
<template>
<router-link class="project-link" :to="{ path: `projects/${url}`, params: { testString: 'a dynamic string' } }" exact>
</template>
<script>
export default {
name: "ProjectCard",
props: {
url: String
}
};
</script>
This will correctly take me to the specified route, eg projects/table. However, the {{ testString }} doesn't render and I can only see the Static text, followed by a portion of the component. There's no errors or warnings in the console.
Checking a ProjectCard component in the Vue debugger, the testString exists nested under to/params/testString:
However, on any of the ProjectPage components, testString is undefined
What am I doing wrong here?
what about this
import ProjectPage from "#/views/ProjectPage.vue"
const routes = [
{
name: 'Project',
path: "projects/:id",
component: ProjectPage,
props: true
}
and
<template>
<router-link class="project-link" :to="{ name: `Project`, params: { testString: 'a dynamic string' ,id: url} }" exact>
</template>
As the docs said
params are ignored if a path is provided, which is not the case for query, as shown in the example above.
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user
The same rules apply for the to property of the router-link component.

Sending props from different routes to the same component using Vue JS

I'm building a menu app using Vue JS. I was told that only have to use 1 component if the styling stays the same. So that means i have to use dynamic data. each menu/submenu has 3 to 4 menu links. I was looking for a solution to send variables with data to a component and came up with 'props'. But i couldn't find a way to send props from different routes to the same component and check which route you're on to know which props to load into the html.
I already tried to load props into a template, and that works fine. But sending and replacing prop values in the same part of html is something i haven't figured out yet.
{ path: '/list', component: List, props: { url: 'www.google.com' } }
<template>
<div class="container">
<h1>Welkom</h1>
<div class="row">
<div class="col-md-6">
<router-link to='/weed'>Wiet</router-link>
</div>
<div class="col-md-6">
<router-link to='/stuff'>Stuff</router-link>
</div>
<div class="col-md-6">
<router-link to='/joint'>Joint</router-link>
</div>
<div class="col-md-6">
<router-link to='/edibles'>Edibles</router-link>
</div>
</div>
</div>
</template>
the <router-link> should dynamic depending on which route you are, so it can load in different menu items.
I want a menu that loads in different route links depending on which route you are.
I think you should use Programmatic Navigation and query params like
router.push({ path: 'register', query: { plan: 'private' } })
so for your application use
<div class="col-md-6"
#click="$router.push({ path: '/edibles',
query: { url: 'www.google.com', other: 'etc' }})"
>Edibles</div>
you can access these query params in the navigated component using $route.params.url in a template and this.$route.params.url in functions and computed and all other properties of vue component instance.
also check https://router.vuejs.org/guide/essentials/navigation.html for details
Edit as per comment
I think you should still use Programmatic Navigation with
router.push({ name: 'user', params: { userId } })
the params provided can be used as props to the component as shown below
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }
]
})
just remember to set props: true in routes definition!
You can use params from your route as props in your component and use a watcher to react to route changes. Either have a state system (vuex) with which you can access specific data regarding the params or just plainly use the params.
Use: router.push({ path: '/user/${userId}' })
then
watch: {
$route(to, from) {
// react somehow
}
}
and/or
template: '<div>User {{ $route.params.id }}</div>'

How to pass data to vue router router-view?

Im using Vue Router. In my code I used to have:
<div v-bind:is="page.component_name" v-bind:page="page"></div>
Which worked, and the page data was passed to the component. But how do I do the same with a router-view? This doesn't seem to work:
<router-view v-bind:page="page"></router-view>
js:
var vm = new Vue({
...,
router : new VueRouter({
routes : [
{ path: '/foo', component: { template: '<div>foo</div>', created:function(){alert(1);} } },
//{ path: '/bar', component: { template: '<div>bar</div>', created:function(){alert(2);} } },
{ path: '/bar', component: Vue.component("ti-page-report") }
]
}),
...
});
vue-router has a dedicated page in docs on how to pass props to router-view.
Passing Props to Route Components
Example snippet from docs:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },
// for routes with named views, you have to define the `props` option for each named view:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
If you are looking for simplified usage, props can still be passed the same way they are passed to any component. But component that is used for rendering the route (the one that is specified in route definition) should expect to receive the props.
Here is simple usage example of passing props to router-view:
I personally decided to use provide/inject feature: preserving reactivity with minimal overhead.
The component ("ti-page-report") that needs to access the props being sent just needs to add it:
<template>
<div>
<h1>Now you can access page: {{ page }}</h1>
</div>
</template>
export default {
name: "TiPageReport",
props: ['page'], // can now be accessed with this.page
...
};
See https://v2.vuejs.org/v2/guide/components-props.html for how to use props properly.

Categories