Bootstrap-Vue - Nav tabs not active for children on router - javascript

Versions:
"bootstrap-vue": "^2.0.0-rc.27",
"vue": "^2.6.10",
"vue-router": "^3.0.3",
My vue-router has children on the /app/groups route. Within the children, I created <b-nav pills> in order to navigate groups however the tabs are not showing up as .active. I'm using params on the routes, not sure if this affects it. Any ideas?
GroupContainer.vue
<template>
<div>
<b-container class="pt-3">
<b-nav pills align="center">
<b-nav-item :to="{ name: 'group.edit', params: { id: this.$route.params.id }}" >Group</b-nav-item>
<b-nav-item :to="{ name: 'group.users', params: { id: this.$route.params.id }}" >Users</b-nav-item>
</b-nav>
</b-container>
<DefaultPage title="Group name" subtitle="Settings">
<router-view></router-view>
</DefaultPage>
</div>
</template>
<script>
import DefaultPage from '../layouts/DefaultPage.vue'
export default {
name: 'GroupContainer',
components: {
DefaultPage
}
}
</script>
router.js
{ path: "/app/group", component: GroupContainer,
children: [
{ path: "", component: NotFound },
{ path: ":id", name: "group.edit", component: GroupEdit },
{ path: ":id/delete", name: "group.delete", component: GroupDelete },
{ path: ":id/users", name: "group.users", component: GroupUsers },
{ path: ":id/users/:userID", name: "group.users.edit", component: GroupEditUser },
{ path: ":id/users/:userID/delete", name: "group.users.delete", component: GroupDeleteUser },
{ path: ":id/add-user", name: "group.addUser", component: GroupAddUser },
]
},

use the active-class or exact-active-class prop, and set it to 'active'
<b-nav pills align="center">
<b-nav-item
:to="{ name: 'group.edit', params: { id: this.$route.params.id }}"
:exact-active-class="active"
>Group</b-nav-item>
<b-nav-item
:to="{ name: 'group.users', params: { id: this.$route.params.id }}"
:exact-active-class="active"
>Users</b-nav-item>
</b-nav>
https://bootstrap-vue.js.org/docs/reference/router-links

Related

vue #/src/assets/images/1.jpg: hasn't been transpiled yet error

**I'm getting this error - vue #/src/assets/images/1.jpg: hasn't been transpiled yet error. I'm looping through tha App component static array. The src is specified correctly though. Using require vue method.
https://codesandbox.io/s/eloquent-grass-j1usw8?file=/src/components/v-carousel-item.vue
**
// APP
<template>
<v-carousel :carousel_data="sliderItems" />
</template>
<script>
import vCarousel from "./components/v-carousel.vue";
export default {
name: "App",
data() {
return {
sliderItems: [
{ id: 1, name: "img1", img: "1.jpg" },
{ id: 2, name: "img2", img: "2.jpg" },
{ id: 3, name: "img3", img: "3.jpg" },
],
};
},
components: {
vCarousel,
},
};
</script>
// Parent
<template>
<div class="container">
<div class="v-carousel">
<v-carousel-item
v-for="item in carousel_data"
:key="item.id"
:item_data="item"
/>
</div>
</div>
</template>
<script>
import vCarouselItem from "./v-carousel-item.vue";
export default {
components: {
vCarouselItem,
},
props: {
carousel_data: {
type: Array,
default: () => [],
},
},
};
</script>
// Child
<template>
<div class="v-carousel-item">
<img :src="require(`../assets/images/` + item_data.img)" alt="" />
</div>
</template>
<script>
export default {
props: {
item_data: {
type: Object,
default: () => {},
},
},
};
</script>
You want to require the images upfront.
export default {
name: "App",
data() {
return {
sliderItems: [
{ id: 1, name: "img1", img: require("#/assets/images/1.jpg") },
{ id: 2, name: "img2", img: require("#/assets/images/2.jpg") },
{ id: 3, name: "img3", img: require("#/assets/images/3.jpg") },
],
};
},
Then update the carousel item component.
<div class="v-carousel-item">
<img :src="item_data.img" alt="" />
</div>
Example: https://codesandbox.io/s/little-bush-ino5zc?file=/src/components/v-carousel-item.vue:11-91

PrimeNG Steps not show in router-outlet

I created a PrimeNG Dialog with Steps module to create a new document, but not showing nothing inside <router-outlet>, what am I doing wrong?
Routes in lazy module Inbox: inbox.module.ts
const routes: Routes = [
{ path: '', component: InboxPageComponent },
{
path: 'new-document', component: NewDocumentComponent,
children: [
{ path: '', redirectTo: 'general', pathMatch: 'full' },
{ path: 'general', component: StepGeneralPageComponent },
{ path: 'flux', component: StepFluxPageComponent },
]
},
];
This is the dialog, inside Inbox template, inbox.component.html:
<p-dialog header="Nuevo Documento" [(visible)]="displayNewDocumentDialog" position="top" [modal]="true"
[style]="{width: '50vw'}" [draggable]="false" [resizable]="false">
<app-new-document></app-new-document>
<ng-template pTemplate="footer">
<p-button label="Limpiar campos" icon="pi pi-refresh" class="p-button-outlined"></p-button>
<p-button label="Guardar y Activar" icon="pi pi-check-circle" class="p-button-outlined"></p-button>
<p-button label="Guardar" icon="pi pi-save" class="p-button-outlined"></p-button>
</ng-template>
</p-dialog>
In component NewDocument:
this.stepItems = [
{ label: 'Generales', routerLink: 'general' },
{ label: 'Flujo documento', routerLink: 'flux' },
{ label: 'Adicionales', routerLink: '' },
{ label: 'Archivado', routerLink: '' }
]
<p-steps [model]="stepItems" [readonly]="false" styleClass="mb-3"></p-steps>
<router-outlet></router-outlet>
This is the result:
Result

Render default child vue-router 4

I'd like to ask about render default child for view.
I know that exists topic with a similar problem but I'm pretty sure that it was for VUE2 and older vue-router. I'm having trouble rendering the default child for view Category. When I'd go to <router-link :to="{ name: routeName, params: { category: item.id } }
everything render okay except <router-view /> it's empty...
I came up with a solution with beforeUpdate(),beforeCreate() but it seems like reinventing the wheel.
If I go to /category/{id} then to /category/{id}/room/{id} and go back one page, the default view will be rendered
How to make the default child load after going to /category/{id}?
router.js
{
path: '/category/:category',
name: 'Category',
props: true,
component: Category,
children: [
{
path: '',
name: 'FavouriteDevicesInCategory',
component: Devices,
props: true,
},
{
path: 'room/:room',
name: 'Devices',
component: Devices,
props: true,
},
],
},
Category.vue - view
<template>
<div class="control">
<div class="left">
[...]
</div>
<div class="right">
<router-view />
</div>
</div>
</template>
<script>
export default {
props: ['category', 'room'],
/** generate default router-view */
beforeUpdate() {
this.$router.push('');
},
beforeCreate() {
this.$router.push('');
},
};
If your default component is Category, you have to create the routes like this:
{
path: '/category',
name: 'Category',
props: true,
component: Category,
children: [
{
path: '/:categoryId',
name: 'FavouriteDevicesInCategory',
component: Devices,
props: true,
},
{
path: 'room/:roomId',
name: 'Devices',
component: Devices,
props: true,
},
],
},
By default it will render the Category component and if you add an id to the url it will go the the Devices component
I think I found a solution, a little messy, but it seems to be the best solution to this problem
{
path: '/category/:category',
// name: 'Category',
props: true,
component: Category,
children: [
{
path: '',
name: 'Category',
component: Devices,
props: true,
},
{
path: 'room/:room',
name: 'Devices',
component: Devices,
props: true,
},
],
},

How to call array values dynamically from an existing array in Vuejs?

HelloWorld.vue
export const datalist = [
{ id: 1, val: "11", kk: "potter" },
{ id: 2, val: "22", kk: "james" },
{ id: 3, val: "55", kk: "limda" },
{ id: 4, val: "77", kk: "stepen" }
];
<template>
<div>
<b>Vuejs dynamic routing</b>
<div v-for="item in items" :key="item.id">
<b>{{ item.id }}.</b>
<router-link :to="{ name: 'UserWithID', params: { id: item.id } }">
{{ item.kk }}
</router-link>
</div>
<br /><br /><br />
<User />
</div>
</template>
<script>
import User from "./User.vue";
import { datalist } from "./datalist";
export default {
name: "HelloWorld",
components: {
User,
},
data() {
return {
items: datalist,
};
},
};
</script>
User.vue
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld.vue";
import book from "./components/book.vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: "/", name: "User", component: HelloWorld },
{ path: "/", name: "BookWithID", component: book },
{ path: "/:id", name: "UserWithID", component: HelloWorld }
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
export const datalisttwo = [
{ id: 1, book: "steel", pen: "p1", gap: "1" },
{ id: 2, book: "iron", pen: "jp2", gap: "5" },
{ id: 3, book: "platinium", pen: "p3", gap: "2" },
{ id: 4, book: "gold", pen: "p4", gap: "9" }
];
<template>
<div>
<router-link :to="{ name: 'BookWithID' }">
{{ user.book }}
</router-link>
</div>
</template>
<script>
import { datalisttwo } from "./datalisttwo";
export default {
name: "User",
components: {},
data() {
return {
lists: datalisttwo,
};
},
computed: {
user: function () {
return this.lists.find((item) => item.id === this.$route.params.id);
},
},
};
</script>
As per the below code, in the datalisttwo.js I have array values like steel and pen Where i want to call both of them together like steel/pen as an api call in the mounted() .
When i click on the router-link, {{ user.book }} from User.vue component.
Ex:- I want to pass the pen/gap array values as query parameters. when clicked on {{ user.book }} from user.vue componet. Please go through codesandbox once, I tried adding computed property for pen and gap. But pen/gap --- but not calling dynamically
Here is my code:- https://codesandbox.io/s/new-hill-6yum4o?file=/src/components/User.vue
Your question and description is quite unclear, so I'll try to answer how I understand it. If that is not what you were expecting, try to explain it again clearly.
First, define your routes clearly. Here your have two routes pointing to '/'. Try to do it to have your user index at '/', your book at '/book/:id', and your user at 'user/:id'.
Second, I am unsure why you have your HelloWorld.vue in both User and UserWithId routes. If intended, disregard. If not, you should clean up that whole file to get the right route pointing to the right component.
Third, used on your example of potter, if you are looking at the book component, for which you haven't provided the code, you can do it such as:
...
computed: {
book() {
if (this.$route.params.id == null || this.$route.params.id == undefined) {
throw new Error('No book id provided')
}
return datalisttwo.find(_ => _.id == this.$route.params.id)
},
pen() {
this.book.pen
},
gap() {
this.book.gap
}
}
...
With this you'll be able to do whatever you whish with this.pen and this .gap.
Now, if you were to want to not import data list again, you can pass your retrieved pen & gap as query parameters: https://router.vuejs.org/api/
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld.vue";
import book from "./components/book.vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: "/", name: "User", component: HelloWorld },
{ path: "/", name: "BookWithID", component: book },
{ path: "/:id", name: "UserWithID", component: HelloWorld }
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
export const datalisttwo = [
{ id: 1, book: "steel", pen: "p1", gap: "1" },
{ id: 2, book: "iron", pen: "jp2", gap: "5" },
{ id: 3, book: "platinium", pen: "p3", gap: "2" },
{ id: 4, book: "gold", pen: "p4", gap: "9" }
];
<template>
<div>
<router-link :to="{ name: 'BookWithID' }">
{{ user.book }}
</router-link>
</div>
</template>
<script>
import { datalisttwo } from "./datalisttwo";
export default {
name: "User",
components: {},
data() {
return {
lists: datalisttwo,
};
},
computed: {
user: function () {
return this.lists.find((item) => item.id === this.$route.params.id);
},
},
};
</script>
I ran this directly.
Error 1:
Imports must be at the top.
Look at 25, 0
Error 2:
Exports must be at the top
Look at 41, 8

Passing props (array) into a router-link path

I'm trying to dynamically update a <router-link> path based on what view component it is used within. Below is the <router-link> that is looping through the compItems array which is populated by each view component.
<router-link :to="{ name: compItem.name, params: { compItems: compItem.router } }" class="cz-ds-view-related-comp" v-for="compItem in compItems" :key="compItem.name">
<div class="related-comp_icon"><img class="related-comp_icon" :src="require('#/assets/home/icons/' + compItem.atomicIcon + '')" alt=""></div>
<div class="related-comp_title"><h3>{{ compItem.name }}</h3> <img src="../../assets/home/icons/arrow-right.svg"></div>
</router-link>
export default {
name: 'relatedSection',
props: {
compItems: {
type: Array
}
}
}
</script>
Below is an example of a view component defining router.
data () {
return {
compItems: [
{ name: 'Links', atomicIcon: 'atom.svg', router: 'links'},
{ name: 'Form Elements', atomicIcon: 'atom.svg', router: 'form-elements'},
{ name: 'Avatars', atomicIcon: 'atom.svg', router: 'avatars'},
{ name: 'Badges', atomicIcon: 'atom.svg', router: 'badges'}
]
}
}
And this is the console error I'm getting.
Thanks in advance!
Edit:
Here's a snapshot of the router file:
const routes = [{
path: '/',
name: 'home',
props: true,
component: Home
}, {
path: '/avatars',
name: 'avatars',
props: true,
component: Avatars
}, {
path: '/badges',
name: 'badges',
props: true,
component: Badges
}, {
path: '/buttons',
name: 'buttons',
props: true,
component: Buttons
}, {
path: '/breadcrumbs',
name: 'breadcrumbs',
props: true,
component: Breadcrumbs
}, {
path: '/form-elements',
name: 'form-elements',
props: true,
component: FormElements
}, {
path: '/icons',
name: 'icons',
props: true,
component: Icons
},
...
The router's route definitions all have lowercase name properties. When you use a <router-link> to access them by name, you need to use an exact match, but your compItems have capitalized names.
Also, you are using route params in the link but none of your routes have any defined.
Here is a refactoring to make the code clearer and correct:
<template v-for="compItem in compItems">
<router-link :to="{ name: compItem.name }" class="cz-ds-view-related-comp">
<div class="related-comp_icon">
<img class="related-comp_icon" :src="require('#/assets/home/icons/' + compItem.atomicIcon + '')" alt="">
</div>
<div class="related-comp_title">
<h3>{{ compItem.title }}</h3>
<img src="../../assets/home/icons/arrow-right.svg">
</div>
</router-link>
</template>
data () {
return {
compItems: [
{ title: 'Links', atomicIcon: 'atom.svg', name: 'links'},
{ title: 'Form Elements', atomicIcon: 'atom.svg', name: 'form-elements'},
{ title: 'Avatars', atomicIcon: 'atom.svg', name: 'avatars'},
{ title: 'Badges', atomicIcon: 'atom.svg', name: 'badges'}
]
}
}

Categories