How to pass Dynamic Props through Routes in Vue 3? - vue.js

I can send static props via <router-link> like so:
parent-component:
<router-link :to="{name: 'child-component'}"></router-link>
child-component:
<template>
<h1>{{ test }}</h1>
</template>
<script setup>
import {defineProps} from "vue";
const props = defineProps({
test: String
})
</script>
router.js:
const router = createRouter({
routes: [
{path: "/child-component", name: "child-component", component: ChildComponent, props: {test: 'hello world'}},
]
});
This correctly displays hello world in the h1 element in child-component. But how do I pass a dynamic element, say a state or prop (parent) through the route?
I've tried:
<router-link :to="{name: 'child-component'}" :props="{test: 'did this come through?'}"></router-link>
or
<router-link :to="{name: 'child-component'}" :test="'did this come through?'"></router-link>
But I don't know what to put instead of hello world:
const router = createRouter({
routes: [
{path: "/child-component", name: "child-component", component: ChildComponent, props: {test: 'hello world'}},
]
});

Here it is,
Router link
<router-link
:to="{
name: 'child-component',
params: { id: id, name: name },
}" >test
</router-link>
// Id and name are dynamic value
route.js file
const router = createRouter({
routes: [
{path: "/child-component/:id/:name", name: "child-component", component: ChildComponent},
]
})
You can access the params at the child component
<span>Name: {{ $route.params.name }} Id: {{ $route.params.id }}
</span>

Related

Vue Router Child showing

I'm trying to make a router with Vue, it works very well, but there is a point in my mind.
Component Child is loaded with "click" at the start of vue, but,
In the Address Bar
When I type "http://127.0.0.1:8000/contact/new" it is displayed that the main component is not started. what is the reason for this?
app.vue
<template>
<router-link :to="{ name: 'home'}">Home</router-link>
<router-link :to="{ name: 'contact'}">Contact</router-link>
<div>
<router-view/>
</div>
</template>
contact.vue
<template>
<div>
Contact Page
<router-link :to="{ name: 'contactNew'}">New Add Contact</router-link>
<div>
<router-view/>
</div>
</div>
</template>
contactAdd.vue
<template>
<div>
Contact New Add
</div>
</template>
router
import Contact from "../Views/contact/Contact.vue";
import Home from "../Views/Home.vue";
import ContactNew from "../Views/contact/ContactNew.vue";
export default [
{
path: '/home',
component: Home,
name: 'home',
},
{
path: '/contact',
component: Contact,
name: 'contact',
children: [
{
path: 'new',
component: ContactNew,
name: 'contactNew',
},
]
},
{
path: '/:pathMatch(.*)*',
redirect: '/home',
}
];

Vue: How to pass custom props and router props?

I'm trying to pass props from one page to another with a redirect. Here's the code for the redirect:
<router-link :to="{ name: 'shipment', params: { editedItems: getSelected() } }">
Edit Amount
</router-link>
And here's the original code for the route in router:
{
path: "/inventory/shipment",
name: "shipment",
props: { screen: "shipment" },
component: Inventory,
},
As can be seen, I want to also pass a set variable, being screen, all the time. The route, shipment, can be called with router-link or through other methods. I know by setting props: true on the route it allows me to get the props sent via the redirect, but it doesn't allow me to pass the screen prop if router-link isn't called. What I'm looking for is the best of both worlds, being able to send both props.
Side note: I know I can easily get the prop on the page by looking at the url, but learning how to do a method like this will be helpful in the future when I don't have an easy out.
With Vue router you can access both information (props and params), just use a different pattern to get it:
const MainView = {
template: `<div>MAIN VIEW: click on TO INVENTORY to see data passed</div>`
}
const Inventory = {
props: ['screen'],
computed: {
routeParams() {
return Object.entries(this.$route.params).map(e => {
return `${e[0]}: ${e[1]}`
}).join(', ')
}
},
template: `
<div>
INVENTORY<br />
prop: {{ screen }}<br />
editedItems: {{ $route.params.editedItems }}<br />
all params: {{ routeParams }}
</div>
`
}
const router = new VueRouter({
routes: [{
path: '/',
name: "main",
component: MainView
}, {
path: '/inventory/shipment',
name: "shipment",
props: {
screen: "shipment"
},
component: Inventory
}]
})
new Vue({
el: "#app",
router
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-link :to="{ name: 'shipment', params: { editedItems: 'someitem' } }">TO INVENTORY</router-link>
<router-link :to="{ name: 'main' }">TO MAIN</router-link>
<router-view></router-view>
</div>

vue-router navigate to the same route and re-run mounted hook

How can I naviagte to the current route using router-link and re-run mounted hook?
HTML
<!-- Include the library in the page -->
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-router"></script>
<!-- App -->
<div id="app">
<nav>
<router-link :to="{ name: 'home' }" exact>Home</router-link>
<router-link :to="{ name: 'about' }" #click.native.prevent="router.push({ name: 'about' })">About</router-link>
</nav>
<router-view :key="$route.fullPath"></router-view>
</div>
JS
console.clear()
console.log('Yes! We are using Vue version', Vue.version)
Vue.use(VueRouter)
const Home = {
template: `<h1>Home</h1>`,
}
const About = {
template: `<h1>{{new Date()}}</h1>`,
mounted(){
console.log('mounted')
}
}
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/about', name: 'about', component: About },
]
const router = new VueRouter({
routes,
})
// New VueJS instance
var app = new Vue({
// CSS selector of the root DOM element
el: '#app',
// Inject the router into the app
router,
})
In the above example, if I navigate to 'About' it shows the timestamp from new Date and logs 'mounted'. However, if I'm already on /about, clicking the about link does nothing. I want to re-run the whole component lifecycle when clicking 'About', even if I'm already hit it.
You'll need to change the key in the <router-view> element whenever the user clicks your about page, that will force the mounted hook:
<template>
<div id="app">
<router-link #click.native="updateViewKey" :to="{ name: 'about' }">About</router-link>
<router-view :key="viewKey"></router-view>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
viewKey: 1
};
},
methods: {
updateViewKey() {
this.viewKey+=1;
}
}
};
</script>
Try this :
router.push({
name: 'routeName',
params: {
id: 'new value'
}
})

Vue Props values not passed in simple test

I'm new using VUE and I was testing a simple vue-router but props are not working in this test.
Here the test on jsfiddle
<div id="app">Menu:
<router-link to="/">Home</router-link> |
<router-link to="/post">Post</router-link> |
<router-link to="/foo">Foo link comment</router-link>
<router-view></router-view>
</div>
const Home = { template: '<div class="page">Welcome to my Home <router-link :to="{name:\'foo\'}">this link</router-link></div>' }
const Foo = {
props:['comment', 'msg'],
template: '<div class="page">{{msg}} Here the comment:<hr><div v-html="comment"></div><hr>Go back to <router-link :to="{name:\'home\'}">home</router-link></div>' }
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', name:'home',component: Home },
{ path: '/foo', name:'foo', component: Foo }],
})
new Vue({
router,
el: '#app',
data: {
msg: 'Hello World',
comment : '<div class="comment">This is a <strong>bold</strong> link</div>'
}
})
And how to pass the router link in prop HTML code?
You need to add props property in routes attribute
{ path: '/foo', name:'foo', component: Foo , props: true}
Also you need to pass prop value in router-link
<router-link :to="{ name: 'foo',
params: { comment: comment,msg: msg }}">Foo link comment</router-link>

Pass an image as prop in a router-link tag

How can I pass an image as prop in a vue-router tag ?
I have :
<router-link :to="{path: '/details', query: {
name: 'item',
//...
}}">
</routerlink
while in my "details" component I have :
<template>
<img :src="url">
</template>
<script>
export default {
name:'child-img',
props:['url'],
data() {
return {
}
}
}
</script>
So it's a case of passing props to your route which you have to set up in your router.
const router = new VueRouter({
routes: [
{ path: '/details/:url', component: Details, props: true },
// ...
]
})
then when you use your route:
<router-link to="`/details/${url}`">Details</router-link>
In the above url is the dynamic element you would be passing to it. If it comes from a v-for loop it would be item.url or whatever you are v-for ing.
OR if you name your route you can pass a param like this:
const router = new VueRouter({
routes: [
{ path: '/details/:url', name: 'Details', component: Details, props: true },
// ...
]
})
then use it like this:
<router-link :to="{ name: 'Details', params: { url } }">
Details
</router-link>
You can read more here