Combining bootstrap-vue and vue-router inside navbar component - javascript

I'm trying to make a navbar with bootstrap-vue that works with vue-router. The navbar is functioning properly but when I click on a navbar item it doesn't route me to the page. The router was working before I incorporated bootstrap-vue so I'm guessing I'm missing something bootstrap related? Any ideas?
Navbar.vue:
<template>
<div>
<b-navbar
toggleable="lg"
type="light"
variant="light"
>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-link
active-class="active"
class="nav-link"
v-for="routes in links"
:key="routes.id"
:to="routes.path"
>
<b-nav-item>
{{ routes.name }}
</b-nav-item>
</b-link>
</b-navbar-nav>
</b-collapse>
</b-navbar>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Navbar',
data() {
return {
links: [
{
id: 0,
name: 'Home',
path: '/',
},
{
id: 1,
name: 'RSVP',
path: '/RSVP',
},
{
id: 2,
name: 'Pictures',
path: '/pictures',
},
{
id: 3,
name: 'Contact',
path: '/contact',
},
],
}
},
}
</script>
router/index.js:
import Vue from 'vue';
import router from 'vue-router';
import Home from '../components/Home';
import RSVP from '../components/RSVP';
import Pictures from '../components/Pictures';
import Contact from '../components/Contact';
Vue.use(router);
export default new router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/RSVP',
name: 'RSVP',
component: RSVP
},
{
path: '/pictures',
name: 'Pictures',
component: Pictures
},
{
path: '/contact',
name: 'Contact',
component: Contact
},
],
mode: 'history',
});
main.js:
import Vue from 'vue';
import App from './App';
import router from './router';
import BootstrapVue from 'bootstrap-vue'
Vue.use(router);
Vue.use(BootstrapVue);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
});
App.vue:
<template>
<div id="app">
<Navbar />
</div>
</template>
<script>
import Home from './components/Home';
import Navbar from './components/Navbar';
import RSVP from './components/RSVP';
import Contact from './components/Contact';
import Pictures from './components/Pictures';
export default {
name: 'app',
created () {
document.title = "title";
},
components: {
Home,
Navbar,
RSVP,
Contact,
Pictures,
},
}
</script>
<style lang="css">
#import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
</style>

According to b-navbar-nav documentation :
Navbar navigation links build on the <b-navbar-nav> parent component and requires the use of and <b-nav-toggle> toggler for proper responsive styling. Navigation in navbars will also grow to occupy as much horizontal space as possible to keep your navbar contents securely aligned.
<b-navbar-nav> supports the following components:
<b-nav-item> for link (and router-link) action items
...
so your code should be like :
<b-nav-item active-class="active" class="nav-link" v-for="routes in links"
:key="routes.id" :to="routes.path" >
{{ routes.name }}
</b-nav-item>

There is more simple way:
<b-navbar-brand :to="{ path: '/' }">To home</b-navbar-brand>

Related

Components are not showing when the routes changing in vue (Vue3, Vue-router)

I'm new in Vue(v.3) and vue-router, before I share the problem with you guys, I searched it inside Stack Overflow and google, but the problem still unresolved.
I define two routes:
/login
/admin/index
Problem:
the login route is working correctly. but
when I try to go to the admin route, it displays the login form instead of the admin panel.
NOTE : I declared <router-view></router-view> inside components/layouts/MasterComponent.vue, and inside App.vue ,I just import the login component.
Here is my code:
routes:
import { createRouter, createWebHistory } from 'vue-router'
import LoginComponent from "../components/auth/LoginComponent";
import MasterComponent from "../components/layouts/MasterComponent";
import ProjectComponent from "../components/ProjectsComponent.vue";
const routes = [{
name: "Login",
path: "/login",
component: LoginComponent,
},
// admin routes
{
name: "Index",
path: "/admin/index",
component: MasterComponent,
children: [{
path: '/admin/projects',
name: 'Projects',
component: ProjectComponent,
}]
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
Master component code:
<template>
<div class="app">
<HeaderComponent />
<LeftMenu />
<div class="main-content">
<section class="section">
<div class="section-body">
<!-- add content here -->
<router-view></router-view>
</div>
</section>
<SiteSetting/>
</div>
<FooterComponent />
</div>
</template>
<script>
import HeaderComponent from "./HeaderComponent.vue";
import LeftMenu from "./LeftMenu.vue";
import FooterComponent from "./FooterComponent.vue";
import SiteSetting from "./SiteSetting.vue";
export default {
name: "MasterComponent",
components: {
HeaderComponent,
LeftMenu,
FooterComponent,
SiteSetting
},
};
</script>
App.vue code
<template>
<LoginComponent/>
</template>
<script>
import LoginComponent from './components/auth/LoginComponent.vue'
export default {
name: 'App',
components: {
LoginComponent
}
}
</script>
<style>
</style>
main.js code
import { createApp } from 'vue'
import App from './App.vue'
import routes from "./routes/route";
import "bootstrap";
import "bootstrap/dist/css/bootstrap.min.css"
const app = createApp(App)
app.use(routes)
app.mount('#app')
PROBLEM SOLVED
I just forgot to put <router-view></router-view> inside App.vue. and also change the routes like this:
// admin routes
{
name: "Index",
path: "/admin",
component: MasterComponent,
redirect: '/dashboard',
children: [{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
}]
},
App.vue before changes:
<template>
<LoginComponent/>
</template>
<script>
import LoginComponent from './components/auth/LoginComponent.vue'
export default {
name: 'App',
components: {
LoginComponent
}
}
</script>
<style>
</style>
App.vue after changes:
<template>
<router-view></router-view>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
</style>

routers and components in vue.js

My component information is not displayed!!!
the router is working great and I test it to many times but there is nothing in components when I run the project.
They all seem to have nothing in them buy I put lot`s of things in them.
I working with vue.js 2
and I have an error in console "You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build."
app.vue:
<template>
<div>
<router-link to="/">app</router-link>
<router-link to="/RoutOne">RoutOne</router-link>
<router-link to="/RoutTwo">RoutTwo</router-link>
<router-link to="/RoutThree">RoutThree</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {},
};
main.js:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import RoutOne from "./router/RoutOne.vue";
import RoutTwo from "./router/RoutTwo.vue";
import RoutThree from "./router/RoutThree.vue";
Vue.use(VueRouter)
const routes = [
{ path: "/", component: App },
{ path: "/RoutOne", component: RoutOne },
{ path: "/RoutTwo", component: RoutTwo },
{ path: "/RoutThree", component: RoutThree },
]
const app = new Vue({
router: new VueRouter({
routes
}),
component: app
}).$mount('#app')
component one:
<template>
<div >
<h1>someone you loved</h1>
<title></title>
<button>nothing</button>
<input disabled placeholder="nothing"/>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
component two:
<template>
<div >
<h1>loving you is a losing game</h1>
<h2>the title is : {{title}}</h2>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
component three:
<template>
<div >
<h1>and way down we go</h1>
<b-alert>wrong side</b-alert>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
Just add mode: 'history' to your router, by default vue-router use hash mode, it uses a hash character (#) before the actual URL is internally passed.
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import RoutOne from "./router/RoutOne.vue";
import RoutTwo from "./router/RoutTwo.vue";
import RoutThree from "./router/RoutThree.vue";
Vue.use(VueRouter)
const routes = [
{ path: "/", component: App },
{ path: "/RoutOne", component: RoutOne },
{ path: "/RoutTwo", component: RoutTwo },
{ path: "/RoutThree", component: RoutThree },
]
const app = new Vue({
router: new VueRouter({
mode: "history",
routes,
}),
component: app
}).$mount('#app')

Why is my Vue navbar changing the route but not updating the router-view?

I'm using Vue to make a single-page application and I have a navbar and have set up Vue-Router. For some reason, every time after the first time I use the navbar, the route changes but the router-view does not. Here's the code from NavBar.vue:
<template>
<div id="app">
<v-toolbar id="navbar" app color="#330066" dark>
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title id="appname">{{ appname }}</v-toolbar-title>
<v-spacer></v-spacer>
<span :key="item.link" v-for="item in items" class="nav-elt">
<router-link active-class="nav-elt-active" tag="span" :to="item.link">
{{ item.title }}
</router-link>
</span>
</v-toolbar>
</div>
</template>
<script>
export default {
name: "NavBar",
props: {
appname: String,
},
data() {
return {
items: [
{ title: "Home", link: "/" },
{ title: "Search", link: "/search" },
],
};
},
};
</script>
And here's from App.vue:
<template>
<v-app>
<v-main>
<NavBar appname="Newsfacts" />
<router-view />
</v-main>
</v-app>
</template>
<script>
import NavBar from "./components/NavBar";
export default {
name: "App",
components: {
NavBar,
},
data() {
return {};
},
};
</script>
Here's from router/index.js:
import Vue from 'vue';
import Router from 'vue-router';
import Home from '../views/Home.vue';
import Search from '../views/Search.vue';
Vue.use(Router);
export default new Router({
mode: "history",
routes: [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/search",
name: "Search",
component: Search
}
]
});
If you need anything else, the full code is on my github, and a demo is at a netlify site
The link attribute inside the array of items should contain a '/' at the beginning of every route.
So, it should look like this:
data() {
return {
items: [
{ title: "Home", link: "/home" },
{ title: "Search", link: "/search" },
],
};
},
Also, it is probable that the component is not being rendered because you are using <v-btn/> for routing, instead of <router-link/>.
I recommend you use <router-link/> instead of <v-btn/> for navigation in order to support all the features provided by Vue Router like history mode, base, etc.
In case you necessarily need the v-btn, I think you can wrap the <router-link/> inside the button or viceversa.
For more information about Vue Router and <router-link/>, check out this link:
https://router.vuejs.org/api/#router-link
where is your vue router component definitions?
e.g
const FooHome= { template: '<div>Home</div>' }
const Search= { template: '<div>Search</div>' }
const routes = [
{ path: '/', component: Home},
{ path: '/search', component: Search}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
Turns out I was returning an empty dictionary in a few data() functions, and that caused the app to break. Thanks to #inked6233 on the Vue Land discord for helping me find that!

Can't navigate through my different router-link using VueRouter

I'm working for the first time with a project created using vue-cli. I'm using VueRouter to navigate between multiple views. The problem is that if I visit de route '/workshops', '/categories' or '/machines', it's always the 'Workshops' component that show up...
Here's my router declaration:
import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'
import Home from '../views/Home.vue'
import Categories from '../views/Categories.vue';
import Machines from '../views/Machines.vue';
import Workshops from '../views/Workshops.vue';
Vue.use(VueRouter)
const routes: Array<RouteConfig> = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/categories',
name: 'Categories',
component: Categories
},
{
path: '/machines',
name: 'Machines',
component: Machines
},
{
path: '/workshops',
name: 'Workshops',
component: Workshops
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
Which is pretty similar to what is declared by default
And here is the declaration of the Workshop component (but Machines and Categories uses the exact same structure)
<template>
<div class="workshops">
<h1>Workshops</h1>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default class Workshops extends Vue {
}
</script>
And Categories.vue as an example:
<template>
<div class="categories">
<h1>Catégories</h1>
</div>
</template>
<script lang="ts">
import { Vue } from 'vue-property-decorator';
export default class Categories extends Vue {}
</script>
The main App.vue is declared as following:
<template>
<div id="app">
<header>
<nav>
<h2 class="brand-name">Flexshop</h2>
<hr>
<ul>
<li><router-link to="/workshops">Ateliers</router-link></li>
<li><router-link to="/categories">Catégories</router-link></li>
<li><router-link to="/machines">Machines</router-link></li>
</ul>
<div class="bottom">
<ul>
<router-link to="/settings">Options</router-link>
<router-link to="/credits">Crédits</router-link>
</ul>
</div>
</nav>
</header>
<main>
<transition name="fade">
<router-view></router-view>
</transition>
</main>
</div>
</template>
If I only use one of the three routes in the router declarations, the correct component shows up, it seems like the declaration the latest components overwrite the two others...
Thanks for your help !
You should use component decorator, like this
<template>
<div class="workshops">
<h1>Workshops</h1>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
#Component
export default class Workshops extends Vue {
}
</script>

pass in props to vue-router, with boostrap-vue b-nav-item

I'm trying to change my SPA from being modals that load components into routed pages that load components. I can open a page using to="/fixtures" in the html but I can't pass in a component that has a prop with some data. How do I pass a prop of fixtures using vue-router and the bootstrap-vue <b-nav tabs> <b-nav-item>?
Home.vue NOT WORKING:
<b-nav-item to="/fixtures" :fixtures="fixtures">Fixtures</b-nav-item>
index.js from router:
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "#/components/Home.vue";
import Scorers from "#/components/Scorers.vue"
import LeagueTable from "#/components/LeagueTable";
import Fixtures from "#/components/Fixtures";
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/fixtures",
name: "Fixtures",
component: Fixtures,
props: true
}
],
mode: "history"
});
Using modals this method works:
<b-tab title="Fixtures">
<Fixtures :fixtures="fixtures" />
</b-tab>
To pass props as part of the route, use this:
<b-nav-item :to="{ path: '/fixtures', props: { fixtures: fixtures } }">Fixtures</b-nav-item>

Categories

Resources