Vue-Router only works on some routes - javascript

My vue-router routes the URL on all menu buttons correctly, but does not show each Vue component properly. A demonstration can be found here.
Inside of my HTML (I am using Vuefy)
<div class="navbar-start">
<a class="navbar-item">
<router-link to="/" class="router-link"> // <-- THIS WORKS
Home
</router-link>
</a>
<a class="navbar-item">
<router-link to="/items" class="router-link"> // <-- THIS WORKS
My Products
</router-link>
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
<router-link to="/information" class="router-link"> // <-- DOES NOT WORK
Info
</router-link>
</a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item">
<router-link to="/about" class="router-link"> // <-- THIS WORKS
About
</router-link>
</a>
<a class="navbar-item">
<router-link to="/terms" class="router-link"> // <-- DOES NOT WORK
Terms
</router-link>
</a>
</div>
</div>
</div>
My router.js file is set up the following:
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue')
},
{
path: '/new',
name: 'create-item',
component: () => import('./views/CreateItem.vue')
},
{
path: '/',
name: 'home',
component: Home
},
{
path: '/items',
name: 'my-items',
component: () => import('./views/MyItems.vue')
},
{
path: '/signin',
name: 'sign-in',
components: () => import('./views/SignIn.vue')
},
{
path: '/terms',
name: 'terms',
components: () => import('./views/Terms.vue')
},
{
path: '/information',
name: 'info',
components: () => import('./views/Info.vue')
}
]
})
Additionally, my App.vue file shows the router-view properly, along with the menu.
<template>
<div id="app">
<div id="nav">
<Menu/>
</div>
<router-view/>
</div>
</template>
<script type="text/javascript">
import Menu from '#/components/Menu.vue'
export default {
components: {
Menu
}
}
</script>
The following is a photograph of my navigation. To repeat, clicking on 'info' and 'terms' (submenu of info) do not load their respective Vue components, but does change the URL.
I triple-checked my syntax and checked the documentation, but could not seem to find my error. The platform at which my code is hosted at can be found here. Any help would be appreciated. Thanks, Edwin.

I found the error. I spelled 'component' instead of 'components' several times in my routes.js file.

Related

Vue Router only applies active class once and not again

WORKAROUND FOUND, SEE EDIT4
my router is acting a bit funny.
It works perfectly for the first link you click, however It doesn't apply the active class after the first time, if I refresh the page it will apply. you can see in the gif here:
Here is my navigation bar code:
<template>
<div class="nav">
<div class="nav__logo-box">
<img src="/logo-no-text-morning.png" :class="$mq" alt />
</div>
<div class="nav__nav-list">
<div class="nav__link">
<router-link to="/" exact-active-class="active-page">
<i class="fas fa-horse-head fa-3x"></i>
<p>Home</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/about" exact-active-class="active-page">
<i class="fas fa-info-circle fa-3x"></i>
<p>About</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/gallery" exact-active-class="active-page">
<i class="fas fa-images fa-3x"></i>
<p>Gallery</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/contact" exact-active-class="active-page">
<i class="fas fa-envelope-open-text fa-3x"></i>
<p>Contact</p>
</router-link>
</div>
</div>
</div>
</template>
Here is my router index.ts
import Vue from "vue"; import VueRouter, { RouteConfig } from "vue-router"; import Home from "../views/Home.vue"; Vue.use(VueRouter); const routes: Array<RouteConfig> = [ {
path: "/",
name: "Home",
component: Home }, {
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("#/views/About.vue") }, {
path: "/contact",
name: "Contact",
// 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("#/views/Contact.vue") }, {
path: "/gallery",
name: "Gallery",
// 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("#/views/Gallery.vue") } ]; const router = new VueRouter({ routes }); export default router;
EDIT:
here's the a look at the web browser debugger:
It for some reason is adding an router-link-active to the home page (probably because its path is just "/").
And then it will add the exact-active just once, but then clicking on another page it will not change. it will stay on the page you was on before, only way to make it change is to refresh the page.
EDIT2:
So now I have decided to store the current page using the following code:
methods: {
getCurrentPage: function() {
this.currentPage = this.$router.currentRoute.name;
}
},
However you can see the behaivour here, it again doesn't update properly and lags behind, it's maybe one or two pages behind where I actaully am.
EDIT3:
I have tried to use a computed method to watch instead but it does not update, it just gets the first page its on and doesnt update again.
data: function() {
return {
currentPage: ""
};
},
computed: {
getCurrentPage: function() {
return this.$router.currentRoute.name;
}
},
mounted() {
console.log(this.$router.currentRoute.name);
this.currentPage === this.getCurrentPage;
}
EDIT4: (WORKAROUND FOUND)
So with the help of the comments, I've got a workaround that will work for now. it's this:
computed: {
getCurrentPage: function() {
return this.$route.name;
}
}
On the links I then bind the active page class:
<div class="nav__nav-list">
<div class="nav__link">
<router-link to="/" :class="{ currentpage: getCurrentPage === 'Home' }">
<i class="fas fa-horse-head fa-3x"></i>
<p ref="homeLink">Home</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/about" :class="{ currentpage: getCurrentPage === 'About' }">
<i class="fas fa-info-circle fa-3x"></i>
<p ref="aboutLink">About</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/gallery" :class="{ currentpage: getCurrentPage === 'Gallery' }">
<i class="fas fa-images fa-3x"></i>
<p ref="galleryLink">Gallery</p>
</router-link>
</div>
<div class="nav__link">
<router-link to="/contact" :class="{ currentpage: getCurrentPage === 'Contact' }">
<i class="fas fa-envelope-open-text fa-3x"></i>
<p ref="contactLink">Contact</p>
</router-link>
</div>
</div>

Can not retrieve component template while routing

I am using Vuejs. This is main js:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
router
}).$mount('#app')
This is router:
import Vue from 'vue';
import VueRouter from 'vue-router';
import ControlExcel from './components/ControlExcel';
import Login from "./components/Login";
import blog from './components/blog';
import file from './components/file';
Vue.use(VueRouter);
let routes = [
{
path: '/control-excel',
name: 'ControlExcel',
component: ControlExcel
}
,
{
path: '/loginn',
component: Login
}
,
{
path: '/blog',
name: 'blog',
component: blog
}
,
{
path: '/file',
name: 'file',
component: file
},
];
export default new VueRouter({
mode: 'history',
base: "",
routes
})
and this app vue:
<template>
<div id="app">
<!-- <img alt="Vue logo" src="./assets/logo.png">-->
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/>-->
<!-- <ControlExcel />-->
<!-- <component v-bind:is="component" />-->
<span>abcd</span>
<li class="nav-item">
<router-link class="nav-link" to="/control-excel">exce</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/loginn">loginn</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/blog">blog</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/file">file</router-link>
</li>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
// import Login from './components/Login.vue'
// import ControlExcel from "./components/ControlExcel";
// import Login from "./components/Login";
import file from './components/file';
import Vue from 'vue';
Vue.component('file',file);
// import DownloadExcel from './components/DownloadExcel'
export default {
name: 'app',
components: {
// Login,
// ControlExcel,
}
,
data() {
return {
// component: "Login"
}
}
}
</script>
At localhost:8080, i see those:
abcd
exce
loginn
blog
file
When i click any of them, URl changes. for example
http://localhost:8080/file
for file but it does not bring component.
for example for file:
{
path: '/file',
name: 'file',
component: file
},
that component file.vue
<template>
<div class="blog">
<h1>fasfsasd</h1>
</div>
</template>
<script>
export default{
name:'file'
}
</script>
<style scoped>
</style>
This is directory:
src
-components
--blog.vue
--ControlExcel.vue
--file.vue
--Login.vue
router.js
main.js
App.vue
Why cant it bring template also?
There is dynamic component but i dont want to use it and it does not seem best practice, like this:
<component v-bind:is=”currentComponent”></component>
https://blog.logrocket.com/how-to-make-your-components-dynamic-in-vue-js/
Your Vue-Router does not change the main component, but only puts the component of the URL that matches into <router-view></router-view>, which you don't have.
You need to add it to your main component.
For example like this:
<div id="app">
<span>abcd</span>
<ul>
<li class="nav-item">
<router-link class="nav-link" to="/control-excel">exce</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/loginn">loginn</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/blog">blog</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/file">file</router-link>
</li>
</ul>
<router-view></router-view>
</div>

Passing json data from one vue page to another vue page and render the chart

I am traversing a json data inside a table in vue and passing some of it to a different page using router link.
Projects.vue
<tbody class>
<tr v-for="project in projects" aria-rowindex="1" class>
<td aria-colindex="1" class>{{project.name}}</td>
<td aria-colindex="2" class>{{project.date}}</td>
<td aria-colindex="3" style="width: 100px">
<router-link to={name: 'Performance', params: {{project.Line_base}} }>
<i class="fa fa-eye"></i>
</router-link>
<i class="fa fa-edit"></i>
<i class="fa fa-remove icons" style="color: red"></i>
<i class="fa fa-share-alt"></i>
</td>
<!-- <td aria-colindex="4" class>{{project.short_description}}</td> -->
</tr>
import axios from 'axios';
import Performance from "./Performance";
export default {
components: {
Performance
},
name: "builder-basic",
data() {
return {
projects: []
};
},
mounted () {
axios
.get('http://some.api.net/v1/projects/')
.then(response => (this. projects = response.data.entities))
},
};
</script>
This project.Line_base is an array of integers, that I want to pass to
Performance.vue
<template>
<div class="animated fadeIn">
<b-card header-tag="header" footer-tag="footer">
<div slot="header">Performance - Models vs Baseline</div>
<div class="card-body" >
<div class="chart-wrapper" >
<b-card header="Lift Chart" >
<div class="chart-wrapper">
<line-example chartId="chart-line-01" :styles="chartStyle" />
</div>
</b-card>
</div>
</div>
<div class="card-body" >
<div class="chart-wrapper">
<b-card header="Accuracy & Sensitivity" >
<bar-example chartId="chart-bar-01" :styles="chartStyle" />
</b-card>
</div>
</div>
</b-card>
</div>
</template>
<script>
import axios from "axios";
import LineExample from "./charts/LineExample";
import BarExample from "./charts/BarExample";
export default {
name: 'Performance',
components: {
LineExample,
BarExample
},
computed: {
chartStyle () {
return {
height: '500px',
position: 'relative'
}
}
}
}
};
</script>
I have the index.js where I have mentioned the routers, which are working well if I am not passing any data to performance, from where I will generate a graph using charts.
index.js
let router = new Router({
mode: 'hash', // https://router.vuejs.org/api/#mode
linkActiveClass: 'open active',
scrollBehavior: () => ({ y: 0 }),
routes: [
{
path: '/',
redirect: '/dashboard',
name: 'Home',
component: DefaultContainer,
children: [
{
path: 'Performance',
name: 'Performance',
component: Performance
}])
The data is not being passed, I followed some of the articles already discussed on stack overflow
Send the params like this;
<router-link :to="{name: 'Performance', params: { Line_base: project.Line_base }}">
<i class="fa fa-eye"></i>
</router-link>
In your Performance.vue Component you need to get de params from the route like this.
computed: {
lineBase () {
return this.$route.params.Line_base
}
}
It seems like you are making a syntaxerror. This the example from the vue router docs:
<!-- named route -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
Further on in the docs it specifies router-link properties, stating:
route.params
type: Object
An object that contains key/value pairs of dynamic segments and star
segments. If there are no params the value will be an empty object.
Compare that to your code:
<router-link to={name: 'Performance', params: {{project.Line_base}} }>
It seems you are forgetting the semicolon before to (which is shorthand for v-bind:to. Without that whatever comes after will just be passed as a string rather than a javascript expression. This should help.
You could try rewriting to:
<router-link :to="{name: 'Performance', params: {Line_base: project.Line_base} }">
Hope that helps!
EDIT: added clarification

Vue component won't load: did you register the component correctly?

My router has:
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/',
name: 'login',
component: Login,
},
{
path: '/app',
component: Container,
children: [{
path: '',
name: 'home',
component: Home
}]
},
],
});
My Container.vue has:
<template>
<div>
<Navigation />
<router-view />
</div>
</template>
<script>
import Navigation from "./Navigation.vue";
export default {
name: "Container",
props: {
msg: String
}
};
</script>
But I get an error:
Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> at src/components/Container.vue
at src/App.vue
In my Navigation.vue, I have
<template>
<nav class="nav nav-pills flex-column flex-sm-row">
<a class="flex-sm-fill text-sm-center nav-link active" href="#">Active</a>
<a class="flex-sm-fill text-sm-center nav-link" href="#">Longer nav link</a>
<a class="flex-sm-fill text-sm-center nav-link" href="#">Link</a>
<a
class="flex-sm-fill text-sm-center nav-link disabled"
href="#"
tabindex="-1"
aria-disabled="true"
>Disabled</a>
</nav>
</template>
<script>
export default {
name: "Navigation"
};
</script>
You're missing to add components:{Navigation} in Container.vue component
export default {
name: "Container",
props: {
msg: String
},
components:{Navigation}
};

Vuejs routes doesn't work?

Somehow my routes doesn't work? I have seen so many videos about routing in vuejs. And all others do it that way. Is it a bug or what can i do ?
Menu.vue:
<template>
<div class="Menu">
<div class="div" style="margin-top:70px;">
<header class="main-header">
<nav class="main-nav">
<ul class="nav-links">
<router-link to="/"><img id="logo" src="assets/Vue.js_Logo.png"></router-link>
<h2 class="nav-link" style="color:white;">Vue.js</h2>
<router-link class="nav-link" tag="li" to="/"><a>Home</a></router-link>
<router-link class="nav-link" tag="li" to="/info"><a>Info</a></router-link>
<router-link class="nav-link" tag="li" to="/ITkompetencer"><a>IT Kompentencer</a></router-link>
<router-link class="nav-link" tag="li" to="/about"><a>Om mig</a></router-link>
</ul>
</nav>
</header>
</div>
</template>
<script>
export default {
name: 'Menu'
}
</script>
app.vue:
<template>
<div id="app">
<Menu></Menu>
<router-view></router-view>
</div>
</template>
<script>
import Menu from './components/Menu'
import Hello from './components/Hello'
export default {
name: 'App',
components: {
Hello,
Menu
}
}
</script>
I hope there are so genius guys out there :)
First, You need define these routes in main.js
// entry file: main.js or app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import Hello from './components/Hello'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
// the home page
{ path: '/', component: Hello }
]
})
new Vue({
router,
render: h => h(App), // the layout
})
It's easy: https://router.vuejs.org/guide/

Categories

Resources