VueJS props are not passing to component via router-link - vue.js

I have the following link in a VueJS component:
<router-link :to="{ name: 'time', props: { tax: 123, site: site_key }}">Add New Request</router-link>
The Time component has the following code, its always showing the default, instead of the value:
<template>
<div>t {{ tax }} {{site}}</div>
</template>
<script>
export default {
name: "Time",
props: {
tax: {
type: String,
default: 'Vue!'
},
site: {
type: String,
default: 'Vue!'
}
}
}
</script>
EDITED
const router = new Router({
routes: [
{
path: '/',
name:'home',
component: Home,
},
{
path: '/time',
name:'time',
component: Time,
props: { tax: null, site: null }
},
]
})

As seen in Vue Router :
https://router.vuejs.org/guide/essentials/passing-props.html
Props are passed by the params field, so like this :
<router-link :to="{ name: 'time', params: { tax: 123, site: site_key }}">Add New Request</router-link>
for a much more insight on your problem, please include your router.js file.

Related

Navbar selects two drawers at once if one path contains the other in Vue

I'm creating an application in Vue.js with a sidebar.
In v-list-item, in the path :to="link.route", I'm using the names for routes: { name: "dashboard" }.
The problem occurs when the path to one link is contained in a link to the other path.
Eg. path: '/' (dashboard) is contained in path: '/help'.
If I click on Help, then both sidebar drawers are selected:
Template:
<template>
<div>
<v-navigation-drawer v-model="drawer">
<v-list nav dense>
<v-list-item-group>
<v-list-item
v-for="link in links"
:key="link.text"
:to="link.route">
<v-list-item-content>
<v-list-item-title class="white--text">{{
link.text
}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-navigation-drawer>
</div>
</template>
Script:
<script>
export default {
data: () => ({
drawer: true,
}),
computed: {
links() {
return [
{
text: "Dashboard",
route: { name: "dashboard" },
},
{
text: "Help",
route: { name: "help" },
},
];
},
},
};
</script>
Router:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Dashboard from '../views/Dashboard.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'dashboard',
component: Dashboard
},
{
path: '/help',
name: 'help',
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
I fixed my problem by adding path { name: "dashboard", path:'/' }in dashboard route declaration.
Code before:
links() {
return [
{
text: this.$i18n.t("navbar.dashboard"),
route: { name: "dashboard"},
},
{
text: this.$t("navbar.help"),
route: { name: "help"},
},
];
},
Code after:
links() {
return [
{
text: this.$i18n.t("navbar.dashboard"),
route: { name: "dashboard", path:'/' },
},
{
text: this.$t("navbar.help"),
route: { name: "help"},
},
];
},
It's not exactly what I wanted, but it solves the problem.

Vue router-link pass prop getting undefined

This is how I passed the prop:
<router-link :to="{ name: 'Cart', params: { payment_method: 'cod' } }">
Router component is like this:
{
path: "/cart",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
in the receiving route, Props:
props: {
payment_method: String,
},
I am getting undefined as value for payment_method. what is wrong here?
Change your router component path to:
{
path: "/cart/:payment_method",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
Try to set payment_method as slug in route with props:true and catch the route's prop directly in data of vue instance
<router-link :to="{ name: 'Cart', params: { payment_method: 'cod' } }">
{
path: "/cart/:payment_method",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
catch directly in data
data: function () {
return {
payment_method: this.$route.params.payment_method,
};
},
This will resolve your problem

VueRouter sometime change URL but doesn't change component

I'm new in vue3. One of my component have a strange reaction. I use vue router/ router-link tags in many components without problems, but in one of them, when I click a button, url correctly change but doesn't refresh to the new component until I press F5. The structure is not different from other components :(
Thanks in advance
Component :
<template>
<router-link :to="{ name: 'List', params : {pageId : 1 }}"><Btn msg="Retour à la liste des derniers messages"/></router-link>
<div class="originalMsg">
<h3>{{ originMsg.title }}</h3>
<p>Auteur : {{ originMsg.User.firstname +' '+ originMsg.User.lastname}} - Date de rédaction: {{ originMsg.creation_date }}</p>
<div class="content">
{{ originMsg.content }}<br>
<hr>
<router-link :to="{ name: 'NewMessage', query:{ responseTo : originMsg.id}}"><Btn msg="Répondre"/></router-link>
<router-link :to="{ name: 'Modify', query:{ id : originMsg.id, title : originMsg.title, content : originMsg.content}}"><Btn msg="Modifier"/></router-link>
</div>
</div>
<div v-if="responses.length>0" class="responses">
<p v-for="(response, index) in responses" :key="index"> {{ response }}</p>
</div>
</template>
<script>
import Btn from "../components/Button.vue";
export default {
name: "Message",
components:{
Btn
},
data(){
return{
originMsg:{},
responses:[],
}
},
async beforeCreate(){
let tmp = this.$route.query.parentMsg
if(this.$route.query.parentMsg==null){
tmp = this.$route.params.msgId
}
//récupère message d'origine
let parentMsg = await fetch(this.$store.state.src + 'message/' + tmp,{
method: "POST",
headers: {
'authorization': 'bearer ' + localStorage.getItem('token'),
'content-type': 'application/json'
},
body: JSON.stringify({userId:parseInt(localStorage.getItem('userId'))})
});
parentMsg = await parentMsg.json();
this.originMsg = parentMsg.msg;
//récupère tableau de réponses
let responseList = await fetch(this.$store.state.src + 'message/responses/' + tmp,{
method: "POST",
headers: {
'authorization': 'bearer ' + localStorage.getItem('token'),
'content-type': 'application/json'
},
body: JSON.stringify({userId:parseInt(localStorage.getItem('userId'))})
});
responseList = await responseList.json()
this.responses = responseList.list
}
};
</script>
router.js:
import { createRouter, createWebHistory } from 'vue-router'
import Connect from '../views/Connect.vue'
import Signup from '../views/Signup.vue'
import Reinit from '../views/Reinit.vue'
import Welcome from '../views/Welcome.vue'
import Profil from '../views/Profil.vue'
import List from '../views/List.vue'
import Message from '../views/Message.vue'
import NewMessage from '../views/NewMessage.vue'
import NotFound from '../views/NotFound.vue'
const routes = [
{
path: '/',
name: 'Login',
component: Connect
},
{
path: '/signup',
name: 'Signup',
component: Signup
}, {
path: '/reinit',
name: 'Reinit',
component: Reinit
}, {
path: '/home',
name: 'Welcome',
component: Welcome,
children: [{
path: 'list/:pageId',
name:"List",
component: List
},{
path: 'profil/:userId',
name:"Profil",
component: Profil
},{
path: 'message/:msgId',
name: "Message",
component: Message
},{
path: 'message/new',
name: "NewMessage",
component: NewMessage
},{
path: 'message/modify',
name : "Modify",
component: NewMessage
}]
},{ path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound },
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
EDIT : I just see this but don't understand it
screenshot
EDIT2: for some old unknown reasons, I put, in an other component (List.vue), a :
watch: {
$route(to, from) {
if(to !== from){location.reload();}
}
}
When I remove it, it almost works. Now, routing is ok, but the destination component (ex: List) doesn't replace the Message component, but take place above. It's strange because I don't have router views in those components, only in their parent (Welcome.vue) component :(
List and Message components at the same time screenshot :(

vuetify and vue-router active navbar for multiple tabs

I would like to achieve highlighting the same menu in a navbar while browsing different tabs.
As seen on the image above, belong is selected while on the department tab. I still wanted to highlight the belong menu while selecting the selection tab. Please see my code below.
Navbar component
<v-list dense>
<v-list-item v-for="item in items" :to="item.to" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
<script>
export default {
data () {
return {
drawer: true,
items: [
{ to: { name: 'dashboard'}, title: 'Dashboard', icon: 'mdi-account' },
{ to: { name: 'department'}, title: 'Department', icon: 'mdi-home-city' },
{ to: { name: 'salary'}, title: 'Salary', icon: 'mdi-cash' },
],
mini: false,
}
},
}
</script>
Router Tab Component
<template>
<v-tabs class="mb-2" mobile-break-point="200px">
<v-tab v-for="tab in navbarTabs"
:key="tab.id"
:to="tab.to"
>
{{ tab.name }}
</v-tab>
</v-tabs>
</template>
<script>
export default {
data() {
return {
navbarTabs: [
{
id: 0,
name: "Department",
to: { name: 'department' }
},
{
id: 1,
name: "Section",
to: { name: 'section' }
},
]
}
}
}
</script>
Routes.js
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import Dashboard from './views/Dashboard'
import Department from './views/Department'
import Section from './views/Section'
import Salary from './views/Hello'
export const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/dashboard', name: 'dashboard', component: Dashboard },
{ path: '/belong/department', name: 'department', component: Department},
{ path: '/belong/section', name: 'section', component: Section },
{ path: '/salary', name: 'salary', component: Salary},
],
});
The current setup is that department path is connected to the belong menu, but I wanted to make it a dynamic wherein section tab will also set the navbar belong into active.
Both of these components are inside the App.vue (main vue file for routing)
UPDATE: I have now fixed this issue.
Here is what I did with the router.js
export const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/404', component: NotFound },
{ path: '*', redirect: '/404' },
{ path: '/', redirect: '/dashboard' },
{ path: '/dashboard', name: 'dashboard', component: Dashboard },
{ path: '/org', name: 'organization', component: Organization,
children: [
{ path: 'department', name: 'department', component: Department},
{ path: 'section', name: 'section', component: Section },
{ path: 'position', name: 'position', component: Position }
],
},
{ path: '/salary', name: 'salary', component: Salary},
],
});
I created a parent component (organization) that holds all the other sub components (department, section, position) and set them as children.
If there are other best practices to do this, please feel free to share your knowledge.

Vue tree navigation (pluggin) how to map routes

I have used vue-tree-navigation for implement this Tree navigation menu .
When I hit a menu item (eg :- Create item) it should route to the create item component.
But it's only print the name of the route in the navigation bar and doesn't route to any where.
http://localhost:8080/inside#item
how do I fixed this problem?
this is my routes.js file
const routes = [
{ path: "/", component: welcome },
{
path: "/inside",
component: inside,
name: inside,
children: [
{ path: "/category", component: category, name: category },
{ path: "/sub-category", component: subCategory, name: subCategory },
{ path: "/item", component: item, name: item }
]
}
];
This is my component
<template>
<div class="inside">
<div class="sideBar"><vue-tree-navigation :items="items" /></div>
<div class="content"><router-view></router-view></div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ name: 'Item Master', route: 'inside', children: [ // /about
{ name: 'Create item category', element: 'category', },
{ name: 'Create item sub category', element: 'sub-category', },
{ name: 'Create item', element: 'item', },
]},
],
};
}
};
</script>
Try to change a bit of things in the router file, it works well for me:
The components starts in Uppercase (just a convention)
The name with ''
Delete the / in the path
Like this:
path: "inside",
component: Inside,
name: "inside",
children: [
{ path: "category", component: Category, name: 'category' },
{ path: "sub-category", component: SubCategory, name: 'subCategory' },
{ path: "item", component: Item, name: 'item' }
]
And the most important, load (if you are not doing it already) the VueRouter with:
var router = new VueRouter({
const routes = [
...
]
});
Hope it helps!