vue-router should route on click, not working - vue.js

I am trying to create a navigation and when someone clicks. It should navigate to another Vue.component.
Note: This app is Electron+Vue based, but it should work as normal Vue Project, as i've tried same concept in other Electron+Vue Project too.
Right now it shows no Content because of error of Router.
Am i missing anything?
Error Shows like this in Screenshot
===================================
----HelloWorld.vue-----
<template>
<div class="collapse navbar-collapse nav-item-outer" id="navbarNav">
<ul class="nav navbar-nav nav-list">
<li class="nav-item active" #click="navigate('information')">
<span class="nav-item-icon nav-item-icon-info"></span>
<span class="nav-item-title">Info</span>
</li>
<li class="nav-item" #click="navigate('map')">
<span class="nav-item-icon nav-item-icon-location"></span>
<span class="nav-item-title">Location</span>
</li>
<li class="nav-item" #click="navigate('videocontent')">
<span class="nav-item-icon nav-item-icon-video"></span>
<span class="nav-item-title">Video</span>
</li>
<li class="nav-item" #click="navigate('surfstation')">
<span class="nav-item-icon nav-item-icon-surf"></span>
<span class="nav-item-title">Surf</span>
</li>
<li class="nav-item" #click="navigate('telephone')">
<span class="nav-item-icon nav-item-icon-telephone"></span>
<span class="nav-item-title">Telefon</span>
</li>
<li class="nav-item" #click="navigate('/')">
<span class="nav-item-icon nav-item-icon-home"></span>
<span class="nav-item-title">Home</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
methods: {
navigate(route) {
this.$router.push(route)
},
}
}
</script>
===================================================
----main.js-------
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
Vue.config.productionTip = false
Vue.use(VueRouter)
export default new VueRouter({
routes: [
{
path: '/',
name: 'dashboard',
component: require('#/views/Dashboard').default
},
{
path: '/information',
name: 'information',
component: require('#/views/Information').default
},
{
path: '/map',
name: 'map',
component: require('#/views/Map').default
},
{
path: '/surfstation',
name: 'surfstation',
component: require('#/views/Surfstation').default
},
{
path: '/telephone',
name: 'telephone',
component: require('#/views/Telephone').default
},
{
path: '/videocontent',
name: 'videocontent',
component: require('#/views/VideoContent').default
},
{
path: '*',
redirect: '/'
}
]
})
new Vue({
render: function (h) { return h(App) },
}).$mount('#app')
=====================================================
----App.vue------
<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<main>
<router-view></router-view>
</main>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
A help would be Appreciated.

Instead of exporting the router, put in a const and specify it inside new Vue({
main.js
const router = new VueRouter({
routes: [
...
],
// Prevent white screen on reload (in production build)
mode: process.env.IS_ELECTRON ? 'hash' : 'history'
})
new Vue({
router,
render: h => h(App),
mounted () {
// Prevent white screen when the app is launched (in production build)
this.$router.push('/').catch(error => { })
}
}).$mount('#app')

Related

NavBar in Vue using v-for and router

I have this default vue navbar which I want to make it more dynamic by using v-for.
Before changes, this is the code:
<template>
<div>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
</template>
After changes, this is the code:
<template>
<div>
<div v-for="navbar in navbars" :key="navbar.id">
<router-link :to="navbar.router">{{ navbar.names }}</router-link>
</div>
</div>
</template>
<script>
export default {
name: "Header",
navbars: [
{ names: "Home", router: "/" },
{ names: "About", router: "/About" }
]
};
</script>
But after converted it, the navbar doesn't show up. Anything I miss out?
You need to define navbars as a data of the component using data
<template>
<div>
<div v-for="navbar in navbars" :key="navbar.id">
<router-link :to="navbar.router">{{ navbar.names }}</router-link>
</div>
</div>
</template>
<script>
export default {
name: "Header",
data: function () {
return {
navbars: [
{ names: "Home", router: "/" },
{ names: "About", router: "/About" }
]
}
}
};
</script>

Vue Js: Props not being passed to component, only showing on page refresh

I'm new to Vue and obviously I'm missing something fundamental here.
I have an app with a list of items, click on one of the items and a new "single" view appears. However the props aren't making it into the single view unless I refresh the page.
Here's an abbreviated version of the main markup items in question:
<div class="container-fluid" id="app">
<div class="row">
<router-view name="default" :partners=partners :partner="partner"></router-view>
<router-view name="list" :filtered="filtered" ></router-view>
<router-view name="modalform" :showmodal="showmodal" :partner="partner" :form="form"></router-view>
</div>
</div>
<script id="list-template" type="text/template">
<div class="col-lg-9" id="list">
<div class="row">
<div class="col-md-6 col-lg-4" v-for="partner in filtered">
<router-link class="link" :to="{ name: 'single', params: { partnerId: partner.id }}">
<h6>${partner.name}</h6>
</router-link>
</div>
</div>
</div>
</script>
Here's my route:
const routes = [
{
path: '/',
components:
{
default: Vue.component('sidebar'),
list: Vue.component('list')
},
props: {
default: true,
list: true
}
},
{
path: '/:partnerId',
name: 'single',
components: {
default: Vue.component('single'),
modal: Vue.component('modalform')
},
props: {
default: true,
modal: true
}
}
]
And here's a shortened version of my component:
Vue.component("single", {
template: '#single-template',
delimiters: ['${', '}'],
props: ["partners", "partner"]
})

Clicking routes in Header refreshes page in vuejs with prerender-spa plugin after serving dist

The connection in between components gets disrupted. Which shouldnt happen since I am using bootstrap-vue inbuilt router link (using to=" " instead of href="").
The app works perfectly fine when running without dist.
App.vue
<template>
<div class="container">
<app-header></app-header>
<div class="row">
<div class="col-xs-12">
<transition name="slide" mode="out-in">
<router-view></router-view>
</transition>
</div>
</div>
</div>
</template>
<script>
import Header from "./components/Header.vue";
export default {
components: {
appHeader: Header
},
created() {
this.$store.dispatch("initStocks");
}
};
</script>
Header.vue
<template>
<div>
<b-navbar toggleable="lg" type="dark" variant="info">
<b-navbar-brand to="/">Stock Broker</b-navbar-brand>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-nav-item to="/portfolio">Portfolio</b-nav-item>
<b-nav-item to="/stocks">Stocks</b-nav-item>
<b-nav-item #click="endDay">End Day</b-nav-item>
<b-navbar-nav right>
<b-nav-item right>Funds: {{ funds }}</b-nav-item>
</b-navbar-nav>
</b-navbar-nav>
</b-collapse>
</b-navbar>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
data() {
return {
isDropdownOpen: false
};
},
computed: {
funds() {
return this.$store.getters.funds;
}
},
methods: {
...mapActions({
randomizeStocks: "randomizeStocks",
fetchData: "loadData"
}),
endDay() {
this.randomizeStocks();
},
saveData() {
const data = {
funds: this.$store.getters.funds,
stockPortfolio: this.$store.getters.stockPortfolio,
stocks: this.$store.getters.stocks
};
this.$http.put("data.json", data);
},
loadData() {
this.fetchData();
}
}
};
</script>
vue.config.js
module.exports = {
pluginOptions: {
prerenderSpa: {
registry: undefined,
renderRoutes: ["/", "/portfolio", "/stocks"],
useRenderEvent: true,
headless: true,
onlyProduction: true
}
}
};
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/stocks',
name: 'Stocks',
component: () => import(/ '../views/Stocks.vue')
},
{
path: '/portfolio',
name: 'Portfolio',
component: () => import('../views/Portfolio.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
I figured it a minute after making this post haha.
The issue was that in App.vue I had my main div with a class of "container" instead of id of "app".
Corrected below:
<template>
<div id="app"> //correction here
<app-header></app-header>
<div class="row">
<div class="col-xs-12">
<transition name="slide" mode="out-in">
<router-view></router-view>
</transition>
</div>
</div>
</div>
</template>

How do I implement breadcrumbs with complete links in vue.js

I have managed to implement breadcrumbs in my vue.js application using npm.
But I'd like my breadcrumb to display a link to previous page, with the link to the current page(id included) next to it. Like this:
Home Page > Details page (as clickeble links)
I've tried following the example from this link https://www.npmjs.com/package/vue-2-breadcrumbs]
this is my index.js file
import Vue from 'vue'
import Details from '#/components/Details'
import Router from 'vue-router'
import HomePage from '#/components/HomePage'
import VueBreadcrumbs from 'vue-2-breadcrumbs'
Vue.use(Router)
Vue.use(VueBreadcrumbs,{
template:
' <ul class="breadcrumb">\n' +
' <li v-for="(crumb, key) in $breadcrumbs" v-if="crumb.meta.breadcrumb" :key="key" class="breadcrumb-item active" aria-current="page">\n' +
' <router-link :to="{ path: getPath(crumb) }">{{ getBreadcrumb(crumb.meta.breadcrumb) }}</router-link>' +
' </li>\n' +
' </ul>\n'
})
export default new Router({
routes: [
{
path: '/',
component: HomePage,
name: 'HomePage',
meta: {
breadcrumb: 'Home Page',
},
},
{
path: '/Details/:id',
component: Details,
meta:{
breadcrumb: function () {
const {name} = this.$route;
return `${name}`;
}
},
name: 'Details',
props: true
}
]
})
It all compiles, and it does render (but only one link, which is to the current page). Now I'd like to add the history link to my breadcrumb (the home page link). How do I do that?
Ok, so I got some inspiration from all of your comments and this is how I fixed it:
So I added one extra <li> to hold the "home page" and the second <li> for looping over the current page... I also wrapped everything inside a root- so no errors about double root elements would occur.
Vue.use(VueBreadcrumbs,{
template:
' <div v-if="$breadcrumbs.length" aria-label="breadcrumb">\n' +
' <ol class="breadcrumb">\n' +
' <li class="breadcrumb-item">Home</li>' +
' <li v-for="(crumb, key) in $breadcrumbs" v-if="crumb.meta.breadcrumb" :key="key" class="breadcrumb-item active" aria-current="page">\n' +
' <router-link :to="{ path: getPath(crumb) }">{{ getBreadcrumb(crumb.meta.breadcrumb) }}</router-link>' +
' </li>\n' +
' </ol>\n' +
' </div>'
})
Thank you everyone for your help!
Add another router-link to your template:
<div id="root">
<router-link :to="/">Home</router-link>
<ul class="breadcrumb">
<li v-for="(crumb, key) in $breadcrumbs" v-if="crumb.meta.breadcrumb" :key="key" class="breadcrumb-item active" aria-current="page">
<router-link :to="{ path: getPath(crumb) }">{{ getBreadcrumb(crumb.meta.breadcrumb) }}</router-link>
</li>
</ul>
</div>
Edit:
Declare your template in this way:
Vue.use(VueBreadcrumbs, {
template: ```
<div id="root">
<router-link :to="/">Home</router-link>
<ul class="breadcrumb">
<li v-for="(crumb, key) in $breadcrumbs" v-if="crumb.meta.breadcrumb" :key="key" class="breadcrumb-item active" aria-current="page">
<router-link :to="{ path: getPath(crumb) }">{{ getBreadcrumb(crumb.meta.breadcrumb) }}</router-link>
</li>
</ul>
</div>
```
})
You can create your own breadcrumb
In file 'index.ts' from router
export let activedRoutes: RouteRecord[] = []
router.beforeEach((to, from, next) => {
activedRoutes = [];
to.matched.forEach((record) => { activedRoutes.push(record) })
next();
});
In route definition
{
path: 'my-path-route',
name: 'MyNameRoute',
component: () => import('./MyComponent/MyComponent.component.vue'),
meta: {
title: 'Title',
icon: 'my-icon',
breadcrumb: { label: 'Label of bradcrumb', routeName: 'MyNameRoute'}
},
}
Create a BreadbrumbComponent
import Vue from 'vue';
import Component from 'vue-class-component';
import { Watch } from 'vue-property-decorator';
import { activedRoutes } from '#/router';
#Component({})
export default class BreadcrumbsComponent extends Vue {
breadcrumbs = []
#Watch('$route')
changeRoute() {
this.breadcrumbs = activedRoutes.map(e => e.meta?.breadcrumb).filter(e => e);
}
created() {
this.changeRoute()
}
}
In html BreadcrumbComponent
<template>
<div class="breadcrumbs" v-if="breadcrumbs.length > 1">
<ul class="v-breadcrumbs">
<template v-for="(item, i) in breadcrumbs">
<li :key="item.label">
<router-link
class="v-breadcrumbs__item"
:to="{ name: item.routeName }"
v-html="item.label"
:class="{ disabled: breadcrumbs.length - 1 == i }"
/>
</li>
<li
v-if="breadcrumbs.length - 1 > i"
class="v-breadcrumbs__divider"
:key="item.label"
>
<v-icon>mdi-chevron-right</v-icon>
</li>
</template>
</ul>
</div>
</template>
In scss of BreadcrumbComponent
.breadcrumbs {
.disabled {
text-decoration: none;
color: rgba(0, 0, 0, 0.38);
cursor: default;
}
}
Now is only use your component where wish
You can use the breadcrumb of vuetify to complement
https://vuetifyjs.com/en/components/breadcrumbs/#large

Vue 2 Laravel 5.3 Vue-router 2 Proper way to set up Vue-router

Just want to set up a simple redirection upon click on something. Not sure how to use vue-router to do such. Please find my codes below:
app.js
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/' },
{ path: '/product', redirect: '/product' }
]
});
const app = new Vue({
el: '#app'
});
Navbar-main.vue
<template>
<ul class="nav navbar-nav">
<li class="nav-item nav-item-left navbar-btn" #click.prevent="goToHome()" #mouseover.prevent="hoverIcon('home')" #mouseleave.prevent="hoverIcon('')">
<div class="nav-link nav-main" :class="[{ 'navbar-home-hover' : hovered == 'home' },{ 'navbar-home' : hovered !== 'home' }]">Home <span class="sr-only">(current)</span></div>
</li>
<li class="nav-item nav-item-left navbar-btn" #click.prevent="goToProduct()" #mouseover.prevent="hoverIcon('product')" #mouseleave.prevent="hoverIcon('')">
<div class="nav-link nav-main" :class="[{ 'navbar-product-hover' : hovered == 'product' },{ 'navbar-product' : hovered !== 'product' }]">Product</div>
</li>
<li class="nav-item nav-item-left navbar-btn" #mouseover.prevent="hoverIcon('blog')" #mouseleave.prevent="hoverIcon('')">
<div class="nav-link nav-main" :class="[{ 'navbar-blog-hover' : hovered == 'blog' },{ 'navbar-blog' : hovered !== 'blog' }]">Blog</div>
</li>
<li class="nav-item nav-item-left navbar-btn" #mouseover.prevent="hoverIcon('mktInfo')" #mouseleave.prevent="hoverIcon('')">
<div class="nav-link nav-main" :class="[{ 'navbar-mktInfo-hover' : hovered == 'mktInfo' },{ 'navbar-mktInfo' : hovered !== 'mktInfo' }]">Market Info</div>
</li>
</ul>
</template>
<script>
export default {
data(){
return{
hovered: '',
}
},
methods:{
hoverIcon(input){
var vm = this
vm.hovered = input
},
goToHome(){
this.$router.push('/');
},
goToProduct(){
this.$router.push('/product');
}
}
}
</script>
error upon click Home
Uncaught TypeError: Cannot read property 'push' of undefined
EDIT#1 (on app.js)
import VueRouter from 'vue-router';
Vue.use(VueRouter); //this is deleted
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/' },
{ path: '/product', redirect: '/product' }
]
});
const app = new Vue({
el: '#app',
router //this is added in this edit
});
It looks like you aren't injecting your router into your app, hence it being 'undefined'
To inject the router make following changes in the Vue app in app.js:
const app = new Vue({
el: '#app',
router // inject the router
});
After that you can use this.$router throughout the app.
Other approach:
You have to import router from app.js like following:
import router from './path/to/app
and after that you can simply use:
router.push