I create router-links with a v-for where I pass params props so I can access them in my router-view. Now I need to have my route props available when a route is accessed other ways than clicking the link, like navigating with $router.go or external URL. How can I pull/sync this data from the existing router-links?
<router-link
v-for="item in items"
:to="{
name: 'Item',
params: {
url: `${item.no}-${item.title.replace(/\s+/g, '-')}`,
no: item.no,
title: item.title
}
}">
{{item.no}}
{{item.title}}
</router-link>
Inside the Item component:
<article :key="no">
<h1> {{ no }} {{ title }} </h1>
</article>
The route:
export default new Router({
routes: [
{
path: '/:url',
name: 'Item',
component: Item,
props: true
}
]
})
I guess the simplest solution is to include the props I need to render in the URL.
<router-link
v-for="item in items"
:to="{
name: 'Item',
params: {
no: item.no,
title: item.title.replace(/\s+/g, '-')
}
}">
{{item.no}}
{{item.title}}
</router-link>
Breaking down the URL like this:
export default new Router({
routes: [
{
path: '/:no/:title',
name: 'Item',
component: Item,
props: true
}
]
})
This way these props
<article :key="no">
<h1> {{ no }} {{ title }} </h1>
</article>
will be available without accessing the route through the link directly.
Related
I'm doing Router with Vue Js, but the thing I want to do is:
Sample:
domain.com/post/1
while the page is open,
again
I don't want it to switch to /post via the menu
Is there a way to prevent this
import Home from "./website/Home.vue";
import Post from "./website/Post.vue";
import PostDetail from "./website/PostDetail.vue";
export default [
{
path: '',
component: Home,
name: 'home',
},
{
path: 'post',
component: Post,
name: 'post',
children: [
{
path: ':id',
name: 'PostDetail',
component: PostDetail,
props: true
}
]
},
]
app.vue
<div>
<router-link to="/">Home</router-link>
<router-link to="/post">Post</router-link>
</div>
<router-view/>
post.vue
<div>
<router-link :to="{name: 'PostDetail', params: {id: 1}}"/>
</div>
<div class="child">
<router-view/>
</div>
postdetail.vue
<div>
Child Component
</div>
I have below my routes
import Cart from './Cart.vue'
import ProductList from './ProductList.vue'
import ViewProduct from './ViewProduct.vue'
export const routes = [
{
path: '/',
name: 'index',
component: ProductList,
},
{
path: '/cart',
name: 'cart',
alias: '/shopping-cart',
component: Cart,
},
{
path: '/product/:product_id/view',
redirect: { name: 'view_product' },
},
{
path: '/product/:product_id',
props: true,
name: 'view_product',
component: ViewProduct,
},
{
path: '*',
component: {
template: '<h1>Page not found</h1>',
},
},
];
And as you can see my route or path /cart has an alias /shopping-cart.
Below are my router links as defined in App.vue with bootstrap#3 styles applied
<ul class="nav navbar-nav">
<router-link
:to="{
name: 'index'
}"
tag="li"
active-class="active"
exact>
<a>Products</a>
</router-link>
<router-link
:to="{
name: 'cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
</ul>
When I navigate to /cart you can see that the active class is applied as in the screenshot below
but when I navigate to the alias /shopping-cart you can see below that the active class is not applied
What can be done so that when I navigate to the alias the active class for the link is also applied?
I have tried to change this
<router-link
:to="{
name: 'cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
to this
<router-link
:to="{
name: 'cart',
alias: 'shopping-cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
but to no avail.
Thank you.
the issue on this is still open in github. Reference: https://github.com/vuejs/vue-router/issues/419
you'll just have to rename your path to /shopping-cart and get rid of alias if you want active-class to be applied.
I have a VueRouter with two levels:
const router = new VueRouter({
routes: [
{
path: '/',
name: 'Home',
component: HomeComponent
},
{
path: '/about',
name: 'About',
component: AboutComponent
children: [
{
path: 'plans',
name: 'Plans',
component: PlansComponent
},
},
]
The App.vue file has the following code:
<template>
<div>
<div>
<nav>
<template v-for="route in routes">
<div>
<router-link class="router-link" :key="route.path" :to="route.path">
{{route.name}}
</router-link>
<div v-for="child in route.children">
<router-link class="router-link router-link-child" :key="child.path" :to="{path: route.path + '/' + child.path}">
{{child.name}}
</router-link>
</div>
</div>
</template>
</nav>
</div>
<router-view></router-view>
</div>
</template>
My problem is that the menu is rendered correctly, but clicking the child item, the component which is rendered is its parent component.
What am I doing wrong?
This is the normal vue-router behavior : if you want the nested route to be rendered, you need to add a <router-view /> inside AboutComponent.
Exemple here : https://jsfiddle.net/yyx990803/L7hscd8h/
The User component contains the <router-view />
I am new to vue and vue router and am using Vue router in history mode. The app contains a menu which is dynamically loaded
<router-link
tag="li"
class="link"
v-for="item in menu"
v-bind:key="item.id"
:to="item.slug"
:exact="item.slug === '/' ? true : false">{{ item.content }}
</router-link>
It works well as long as I stay in the parent routes like http://localhost:8080/posts As soon as I navigate a level deeper, e.g. to a post with the id 8 http://localhost:8080/posts/8 with a routerlink inside the Template
<router-link
tag="h2"
class="link"
:to="{ name: 'post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
it works in one way, but doesnt go back to the parent route when I click the main navigation links. Instead just adds the link of the main menu to the end of the route, e.g. instead of http://localhost:8080/posts
http://localhost:8080/posts/posts
The router
const router = new Router({
mode: 'history',
base: '',
routes: [
{ path: '/', name: 'home', component: HomePage },
{ path: '/posts', name: 'posts', component: PostsPage },
{ path: '/posts/:id', name: 'post', component: SinglePost },
{ path: '/projects', name: 'projects', component: ProjectsPage },
{ path: '/projects/:id', name: 'project', component: ProjectPage },
{ path: '/:page', name: 'page', component: SinglePage },
{ path: "*", redirect: '/' },
],
// etc..
});
I guess I am making a common mistake, but I canĀ“t find a solution. Any help appreciated.
You can use absolute paths. Instead of
<router-link
tag="h2"
class="link"
:to="{ name: 'post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
use
<router-link
tag="h2"
class="link"
:to="{ name: '/post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
The change is /post vs post in router-link's :to attribute.
You could and probably should use nested routes and components for posts posts/:id, but this a little more work and you my not need it at the moment. More on nested routes here.
I have this anchor in Parent.vue:
<a v-link="{ path: '/somepath/somesubpath', query: { messageId: 999}}"> Here </a>
or also this
<a v-link="{ path: '/somepath/somesubpath', params: { messageId: 999}}"> Here </a>
My Child.vue is like this:
<template>
{{messageId}}
// other html..
</template>
<script>
export default {
props: ['messageId']
}
</script>
In Child.vue I can not see the value of {{messageId}} being rendered. This means that the value is not getting passed.
I am using vue router 0.7.5 and the docs here do not specify how to specify params in v-link (without named routes).
So whats the proper way to pass in params using vue router with v-link?
Route params are available in the this.$route.params property. They do not need to be passed as a component property.
In your case you can access the messageId param in your template like so:
{{ $route.params.messageId }}
However, you also need to make sure that the template for your Child.vue component has a single root element and not just text. Otherwise, the component will not render.
So, you'd at least need something like this:
<template>
<div>
{{ $route.params.messageId }}
</div>
</template>
Here's a simple example:
Vue.component('child', {
template: `
<div>
message id: {{ $route.params.messageID }}
</div>
`
});
const Home = {
template: '<div>Home</div>'
};
const Message = {
template: `
<div>
<span>Message View</span>
<child></child>
</div>
`
};
const router = new VueRouter({
routes: [
{ path: '/', component: Home, name: 'home' },
{ path: '/message', component: Message, name: 'message' }
]
})
new Vue({
router,
el: '#app'
})
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<script src="https://npmcdn.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-link :to="{ name: 'home' }">home</router-link>
<router-link :to="{ name: 'message', params: { messageID: 123 } }">message view</router-link>
<router-view></router-view>
</div>