I have a catalog item, by clicking I generate a slug and insert it into the NuxtLink.
Now in the component I need to get a specific element from the array, but I don't have a slug in the array. With the help of id, I would be able to find the desired element. I don't provide any id to Nuxt routing.
If I can somehow get the id of the desired element, then how do I do it?
I think it would be a bad idea to record the id in the pinia store.
How do they act in such situations in general? I use nuxt 3.
<NuxtLink class="catalog-item" :to="`catalog/${slug}`"></NuxtLink>
You can use the params property to pass the id of the desired element as a route parameter.
<NuxtLink class="catalog-item" :to="`catalog/${slug}/${id}`"></NuxtLink>
Then, in the component that is rendered when the NuxtLink is clicked, you can access the id route parameter using the $route.params.id property.
mounted() {
const id = this.$route.params.id
// use the id to get the desired element from the array
}
I would prefer decoupling the router param through props in the Component. Official docs
props: {
id: {
type: Number,
required: true,
},
},
Then in router file you need to enable props:
const routes = [{ path: '/user/:id', component: User, props: true }]
Related
I have a view which shows all posts. There's a filter above those posts and user can filter posts depending on what options he chooses. After he chooses the options, filtered posts get returned.
Let's say user filtered posts and after that clicked on one of the posts, it means that parent component which was showing posts will be destroyed. If now, user(who is on the specific post page) clicks back button, it will take him to all posts page, but filters won't be persisted since parent component got destroyed and then created.
One solution to persist filters and filtered posts after clicking back button from specific page is to use vuex. when user chooses filters, we store the object in vuex. when user clicks back button, store would already have the filters. The problem is following this way causes some problems for me and takes much more time.
Any other way you can think of ? I can't use keep-alive since it seems i can only use it for dynamic components and not any other way.
I see 2 options here:
Vuex - it's used for state management, best to use when you need to communicate between 2+ components. You can will need a set of methods that will update the filter values in your store, e.g.:
const store = {
category: null,
tag: null,
date: null
}
const actions = {
updateFilter({ commit }, payload) {
commit('updateFilter', payload); // example payload structure: { filterName: 'category', filterValue: 'reviews' }
}
}
const mutations = {
updateFilter(state, payload) {
state[payload.filterName] = payload.filterValue;
}
}
export default {
namespaced: true,
store,
actions,
mutations
}
And you need to bind these actions to via #click events on your website. Then you need to bind the values from the store with your filters method (probably also you'll want to execute filtering method when your posts list changes, so you can use watcher for example)
If you're using Vue router and history mode, you can store your filters via query params:
router.push({ path: 'blog', query: { category: 'reviews' }})
So your url will become blog?category=reviews - and when you change your url to clicked article and then click back, you'll go first to the url with latest query params set you had (but of course you need to create a method that will filter out on component create the post list based on provided filters)
The additional win for the 2nd option is that you'll be able to share the link with other people (so they will gonna see the filtered posts in the same way as you do).
I want to send a variable as a prop from a route to another in vue.
I have a vue component, Champions, using a v-for and creating a new component called ChampionCard for each character in a JSON file, and binding the current champion each time.
In ChampionCard, I just show the name and image of the champion.
I want that, when clicking on a ChampionCard, you get redirected to another component called Champion with URL champions/:champion.
But I can't find a way to send the champion data between those 2 routes.
The Champions component :
<div class="champions">
<ChampionCard v-bind:champion="champion" v-for="champion in champions" :key="champion.key">
</ChampionCard>
</div>
The ChampionCard component :
<article #click="redirectTo(champion)" class="champion">
<img class="champion-icon" :src="champion.image" :alt="champion.name">
<h2 class="champion-name"> {{ champion.name }} </h2>
</article>
redirectTo(champion) {
this.$router.push({ name: 'champion', params: { champion: champion.key }})
}
The above code is working as I get redirected to champions/championName, but I don't have access to my champion variable. What would be the best way to send it as a prop in Champion component ?
Thanks :)
My alternative is: While redirecting to champions/:champion route, just send the id of the champion (such as champions/123).
When you are redirecting to this route, you can store champion object in a global place (say store). So that you can lookup with id (123) when you're mounting the route.
One step further, if you cannot find the object in the global store, you can initiate a remote call. So that your route will not be broken if 123 is not in the store. (User can go directly to that route if they save some bookmarks of that page etc.)
To keep your object in the global place, you have different alternatives:
Simple State Management (Simple/Basic implementation)
Using Vuex
I think you can achieve what you want doing something like this:
Declare a new route:
{
path: '/champion/:championKey',
name: 'Some name',
component: ChampionComponent,
}
Then, when redirecting to this new route:
redirectTo(champion) {
this.$router.push("/champion/" + champion.key)
}
Now you can access to the url param like this:
this.$route.params.championKey // as declared in router.js
Simple task to pass data from one page to another made a real headache to newbie in Vue.js
Here is my router
I'm rendering a form on "/" page, which make an API request,
and I just want to pass data to another route page with another component
Is it so hard to do in Vue? It made a real headache for me today.
Get data from API, save & send to another component. How can I do it?
As Antony said, since you've already enabled props in router/index.js, you can pass parameters in router.push like this:
router.push({
name: 'events',
params: {
items: data
}
});
then you will be able to receive items as props in EventsDisplay.vue
export default {
name: 'eventsDisplay',
props: ['items'],
};
If you want to save it globally, you could use an event bus or a VueX store to contain it, then save and load it from this event bus or store when you need to access it.
If you want to pass it between those two components only, and only when accessing the second page from the first one, you can pass properties to the route argument as per this guide: https://router.vuejs.org/en/essentials/passing-props.html
Try using Vuex
In Source Component
this.$store.commit('changeDataState', this.$data);
this.$router.push({name: 'user-post-create'});
In Destination Component
created () {
console.log('state', this.$store);
this.$store.getters.Data;
}
Add props true in your vue router
{
path: "/pay-now",
name: "pay",
props: true,
component: () =>
import(/* webpackChunkName: "about" */ "../components/account/pay.vue"),
beforeEnter: AuthGuard,
},
After that pass props with router like that
this.$router.push({
name: "pay",
params: {
result:this.result,
}
});
I am trying to use nested routing in my Vue.js application. I have the routing working, however I cannot figure out how to pass data from a parent route down to a child route.
Basically, the parent route is going to retrieve an object that has properties. For each specific nested child route, I want to show one of the properties on that object.
For example, if I have the object below:
myDataObject : {name : "Foo" , profile : "Profile Data", posts : "Posts Data" }
I would like to pass the "profile" variable to the child route "/user/:id/profile". In the case of "/user/:id/posts", I would like to pass the "post" variable in.
I thought I could accomplish this using props, but I cannot find an example that fits with routing and what I tried does not seem to work.
Here is a link to a jsfiddle of what I am trying to do.
http://jsfiddle.net/90q4sucj/2/
This is definitely doable with props.
In parent component
<template>
...
<router-view :profile="myDataObject.profile" />
...
</template>
In child component
<script>
export default {
name: "child",
props: ["profile"]
...
Now, in your child component you may access the data by referring to this.$props.profile.
I am using this pattern with Vue 2.5.16. and Vue Router 3.0.1.
PS: A good option is to also use vuex for such scenarios.
See the answer below for the correct answer
! You can retrieve data by using services you create. In the example given I've updated to follow the "fetch data after navigation" sample shown in the docs. It has a userService that will handle getting the user's profile.
! const userService = {
findProfile(id) { return 'Profile Data'; }
};
! Then I updated the UserProfile component to get the profile when it's created and it watches the $route for changes.
! const UserProfile = {
data() { return { profile: null } },
template: 'Profile {{ $route.params.id }} {{ profile }}',
methods: {
setProfile: function () { this.profile = userService.findProfile(this.$route.params.id); }
},
created: function () { this.setProfile(); },
watch: { '$route': 'setProfile' }
}
! As for passing it through like props: [] I didn't see a way but that's probably a good thing because it could start getting pretty convoluted. Here you know explicitly where the user profile is coming from and don't need to follow a rabbit hole to figure it out.
! http://jsfiddle.net/90q4sucj/3/
We have a list of lectures and chapters where the user can select and deselect them. The two lists are stored in a redux store.
Now we want to keep a representation of selected lecture slugs and chapter slugs in the hash tag of the url and any changes to the url should change the store too (two-way-syncing).
What would be the best solution using react-router or even react-router-redux?
We couldn't really find some good examples where the react router is only used to maintain the hash tag of an url and also only updates one component.
I think you don’t need to.
(Sorry for a dismissive answer but it’s the best solution in my experience.)
Store is the source of truth for your data. This is fine.
If you use React Router, let it be the source of truth for your URL state.
You don’t have to keep everything in the store.
For example, considering your use case:
Because the url parameters only contain the slugs of the lectures and the chapters which are selected. In the store I have a list of lectures and chapters with a name, slug and a selected Boolean value.
The problem is you’re duplicating the data. The data in the store (chapter.selected) is duplicated in the React Router state. One solution would be syncing them, but this quickly gets complex. Why not just let React Router be the source of truth for selected chapters?
Your store state would then look like (simplified):
{
// Might be paginated, kept inside a "book", etc:
visibleChapterSlugs: ['intro', 'wow', 'ending'],
// A simple ID dictionary:
chaptersBySlug: {
'intro': {
slug: 'intro',
title: 'Introduction'
},
'wow': {
slug: 'wow',
title: 'All the things'
},
'ending': {
slug: 'ending',
title: 'The End!'
}
}
}
That’s it! Don’t store selected there. Instead let React Router handle it. In your route handler, write something like
function ChapterList({ chapters }) {
return (
<div>
{chapters.map(chapter => <Chapter chapter={chapter} key={chapter.slug} />)}
</div>
)
}
const mapStateToProps = (state, ownProps) => {
// Use props injected by React Router:
const selectedSlugs = ownProps.params.selectedSlugs.split(';')
// Use both state and this information to generate final props:
const chapters = state.visibleChapterSlugs.map(slug => {
return Object.assign({
isSelected: selectedSlugs.indexOf(slug) > -1,
}, state.chaptersBySlug[slug])
})
return { chapters }
}
export default connect(mapStateToProps)(ChapterList)
react-router-redux can help you inject the url stuff to store, so every time hash tag changed, store also.