I'm looking for advice on how to go about this routing scenario:
I have the following HTML that loops category and items in the category. The <router-view>
is inside the category so that when an item is clicked it will open only in the category that related to that item.
<ul>
<li v-for="cat in categories">
<ul>
<li v-for="business in filteredByCat">{{business.name}}</li>
</ul>
<router-view v-if="..."></router-view>
</li>
</ul>
My routes are as follows:
{
path: '/businesses',
name: 'Directory',
component: Directory,
children: [{
path: ':listing',
name: 'Listing',
component: Listing
}]
}
Visualization:
How do I get the data of the item clicked to pass to the router-view
? I assume I'd use props but that wouldn't work if the user visited details directly by URL?
I tried getting the item like so:
methods: {
finalItem ($route) {
var match = this.businesses.filter((business) => {
return business.link === $route.params.listing
})
return match[0]
}
}
This doesn't work, even if it did, this feels wrong. Is there a way to pass the data in a way that would preserve even when visited directly? This is my primary concern. (I understand the repeated <router-view>
is bad code but am not sure how to get around doing that with my layout. Open to suggestions on that too though.)
The way you're using router-view
, you might as well just drop a component in. As far as using multiple router-view
s goes, it's very common, so idk what @varbrad is talking about there. Child routes are fine.
The not-so-common part is using multiple router-view
's in one component. The UI you're aiming for is nearly identical to Netflix. If you check out what they're doing, you'll see that they pass a movie ID (business id/shortname) as "jbv" and a row number (category name) as "jbr" in the route query.
Let's mimic this in your component:
I'm not sure what filteredByCat
looks like, but the way you have it set up, it would list the same businesses for every category. Try something like this:
computed:{
businessesByCategory(){
let dictionary = {};
this.businesses.forEach(business=>{
business.categories.forEach(category=>{ // assuming each business has an array of categories
dictionary[category] = dictionary[category] || [];
dictionary[category].push(business)
})
})
return dictionary;
}
},
data(){
return {
activeBusiness:null
}
},
methods:{
setActiveBusiness(business){
this.activeBusiness = business;
},
setUrlQuery(listing, category){
this.$route.query.listing = listing;
this.$route.query.category = category;
},
openListing(business, category){
this.setActiveBusiness(business);
this.setUrlQuery(business.link, category);
}
}
-
<ul>
<li v-for="cat in categories">
<ul>
<li
v-for="business in businessesByCategory[cat]"
@click="openListing(business, cat)"
>
{{business.name}}
</li>
</ul>
<Listing :business="activeBusiness" v-if="$route.query.category == cat"></Listing>
</li>
</ul>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.