So using router/index.js I managed to at least get the home page displayed. Now I have moved the code to main.js to simplify it for this question, and not even the home page loads. I only get the vue logo:
main.js:
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
import Home from '#/pages/Home.vue'
import DiscussionPage from '#/pages/DiscussionPage.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/discussion-page/:id',
name: 'DiscussionPage',
component: DiscussionPage,
props: true
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
const forumApp = createApp(App)
forumApp.use(router)
forumApp.mount('#app')
Here's the template from the homepage (Home.vue inside src/pages):
<template>
<div class="home">
<p>This is the home page</p>
<div class="discussions" v-for="discussion in discussions" :key="discussion.id">
<router-link :to="{name: 'DiscussionPage', params: {id: discussion.id}}">
{{ discussion.word}}
</router-link>
</div>
</div>
</template>
There was no issues getting the discussions data before I added vue-router, is why I am not including that part of the code. Also, before I moved the code to main.js the url would change when clicking the router-link for the discussion page, but the page would not load.
I am using vue-router4 and I built the app using the CLI with the default vue3 option.
Any clues of what it is I am doing wrong? I am sure it is anobvious little detail, but I can't find it :-(
Thank you so much :-)
This was really silly, but I guess it is still worth publishing for beginners?
For the vue-router to work, one must add the router-view tag. I guess I could have added it in my home page as Bulent suggested. But I think it makes more sense to add it in App.vue so that affects the whole app.
I have to say that this is not clear at all from the current documentation: https://next.router.vuejs.org/guide/#router-link
So simply adding this on App.vue activated the router, and all works well now :
<template>
<router-view/>
</template>
Related
I have just started learning Vue. I actually became confused with the Vue router part. It's a very simple question. I tried looking for many docs and tuts but didn't find anything that I was looking for. It might be my fault on not implementing them correctly which I can understand as a beginner but still got stuck. Let me explain what I am trying to obtain and what I did so far.
This is my Home.vue file and I want user to see this page by default on / path.
<template>
<div>
<MainNavigation />
<LandingSection />
<Services />
<WhyKontext />
<SignupTrial />
<Footer />
</div>
</template>
This is my code for App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./views/landing/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
This is my router.js
import Vue from "vue";
import VueRouter from "vue-router";
import LoginRegister from "./views/account/LoginRegister";
import App from "./App";
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
routes: [
{
path: "/",
component: App,
},
{
path: "/account",
component: LoginRegister,
},
],
});
On MainNavigation.vue there is this block of code
<router-link to="/account" class="bg-color text-white">TRY CONTEXT </router-link>
What I am trying is: If a user clicks on TRY KONTEXT button, I want them to go to Signup/Login page named as LoginRegister.vue.
I tried by putting <router-view></router-view> on MainNavigation but LoginRegister page comes attached with the rest of the Home components. When I am on http://localhost:8080/ then I get complete Home. When I click on TRY KONTEXT button It takes me to http://localhost:8080/account but I still can see All the Home Components along with LoginRegister. I am trying to make MainNavigation and Footer at all pages and Just change the content at middle according to the route. In this case, I actually wanted to see MainNavigation, LoginRegister and Footer. I know it's a silly question. Please help me.
Try putting your router-view in your App.vue, with the basic layout in it, such as header/footer/side_bar. Now, your App.vue should contain something like this:
<template>
<div class="container">
<AppHeader></AppHeader>
<router-view/>
<AppFooter></AppFooter>
</div>
</template>
Then move your Home.vue to a separate file, so that it doesn't contain header and footer which you already included in your layout:
<template>
<div class="container">
<carousel></carousel>
<image-grid></image-grid>
</div>
</template>
Now, in your router.js, specify the routes, almost like this:
import Home from './path/to/home.vue'
routes = [
{
path: '/',
name: 'home',
component: Home
}
]
Try editing your App.vue component template like this:
<template>
<div>
<router-view/>
</div>
</template>
The logic behind this is that the app is showing the current selection of your router.
my single page application is not working and after running my app there is blank page logging in the console that path is required in the router configuration.
this is my main.js
import Vue from 'vue' import VueRouter from 'vue-router';import App from './App.vue'import {routes} from './routes.js'; Vue.use(VueRouter); const router=new VueRouter({routes});new Vue({el: '#app',router:router , render: h => h(App)})
this is my routs.js
import User from './components/User/User.vue';import Home from'./components/Home.vue';import App from './App.vue';export const routes=[{ path:'', component: Home },{ Path:'/user', component:User}];
this is my app temlate
<template> <div class="container">
<div class="row">
<div class="col-lg-12 col-md-6 col-xs-12 col-sm-8 col-sm-offset-2 col-md-offset-3"><h1 class="text-center mt-3">Routing</h1><hr><router-view></router-view>
</div>
</div>
other components are also set like this.
I expected that the app page will be rendered.
In routes.js, For the second route you are adding path as Path, You have to give 'path'. P should be lowercase like this.
routes: [{ path: "/", component: Home }, { path: "/user", component: Hello }]
It would be easier to get to grips with your code if you put some line returns in there.
I can't see your closing </template> tag. That would be an issue.
In your routes.js, try: routes=[{ path:'/', component: Home }{ path:'/user', component:User }] - note the path for home is '/'
Hope that helps
I have a really simple minimal example page with vue-router which is only partially working.
app.js
import 'babel-polyfill';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './app.vue';
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
app.vue
<template>
<div class="container">
<div id="nav">
<router-link to="/">Page 1</router-link>|
<router-link to="/page2">Page 2</router-link>
<router-link to="/sretbs">No page</router-link>
</div>
<div style="border:5px solid green">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
router.js
import Vue from 'vue'
import Router from 'vue-router'
import Page1 from './page1.vue';
import Page2 from './page2.vue';
import ErrorPage from './error.vue';
Vue.use(Router)
export default new Router({
routes: [
{ path: '/page1', name: 'page1', component: Page1 },
{ path: '/page2', name: 'page2', component: Page2 },
{ path: '*', component: ErrorPage }
],
redirect: {
"/": "page1"
}
})
The <router-view> appear to work on first page load. It shows the component I expect for whatever route is currently in the url (e.g. localhost/test#/page2), or if I explicitly route.push before binding Vue to #app it also shows the expected component.
Navigating to other routes doesn't appear to fully work, or at least it's not rendering the new route. When I add debug output to the page components like so:
<template>
<div class="container">
<h2>this is page 2</h2>
<buttons></buttons>
</div>
</template>
<script>
export default {
beforeRouteEnter: function(to, from, next) {
console.log(`Entering page 2:`);
next();
},
beforeRouteLeave: function(to, from, next) {
console.log(`Leaving page 2`);
next();
},
beforeRouteUpdate: function() {
console.log(`Before route update`);
}
};
</script>
it is picking up the routeenter/leave events. I can seemingly navigate back and forth between routes, but you don't see the result until a page reload
I can't recreate the problem in a jsfiddle, and I've scrapped everything and started again but am getting the same result. I can't see anything I'm doing wrong from looking at the Vue Router documentation. Any idea what I'm missing here?
In this instance the answer was painfully simple. There was another Vue instance on the page elsewhere. Even though my understanding is separate Vue instances bound to different container elements should be able to exist in harmony, in this instance it wasn't. It was also what was breaking the Vue dev tools, showing a Vuex instance for example but not showing any of the loaded components and giving a Cannot read property '__VUE_DEVTOOLS_UID__' of undefined error in the Vue Dev Tools errors.
The app works fine on every browser, but when I "Add it to my Home Screen" on my iPad, it loads only the "main" component but none of the children.
Here's my main.js :
import Vue from 'vue'
import router from './router'
import App from '#/App.vue'
Vue.config.productionTip = false
const app = new Vue({
router,
render: (h) => h(App)
}).$mount('#app')
My App.vue :
<template>
<div id="app">
<div class="bg">BEFORE VIEW</div>
<router-view class="view"></router-view>
<div class="bg">AFTER VIEW</div>
</div>
</template>
<script>
require('./assets/styles.css')
</script>
My router/index.js :
import Vue from 'vue'
import VueRouter from 'vue-router'
import Parent from '#/components/Parent'
Vue.use(VueRouter)
export default new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/', component: Parent },
{ path: '/products',
component: Parent
},
{ path: '/clients',
component: Parent
},
{ path: '/verticals',
component: Parent
}
]
})
and the components/Parent.vue :
<template>
<div class="parent">
<p>INSIDE PARENT</p>
</div>
</template>
<script>
export default {
name: 'Parent'
}
</script>
Basically this is meant to be a kind of slide show, the Parent component will detect the current Route and go to the appropriate slide.
As I mentionned, the app works very well both on my desktop (on Chrome) and on my iPad (on Safari), but when I do "Add it to my home screen", all I see are the "BEFORE VIEW" and the "AFTER VIEW" from the App.vue (and the #app element has the right background color) but everything in the just doesn't load.
I feel like an idiot, I'm sure the solution just depends on a tidbit of knowledge I'm missing, but I can't seem to find anyone else with a problem close enough to mine that I can use their solution.
Please help, thank you so much for your time !
I randomly found a solution that makes the desired content appear.
In router/index.js, I removed the line
mode: 'history',
I honestly don't understand yet why it worked, but it does. I'll look further.
Thanks to everyone who took a look at my problem !
I'm trying to get a variable called project_id from the address bar using vue-router. I've initialized a router like so:
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
Vue.config.productionTip = false
Vue.use(VueRouter)
/* eslint-disable no-new */
const router = new VueRouter({
routes: [
{ path: '/project/:project_id', component: App }
]
})
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
And tried to access this.$route.params.project_id from within my App.vue componenet:
<template>
<div id="app">
<img src="./assets/logo.png">
<div id="center_bar">
oh: {{this.$route.params.project_id}}
</div>
</div>
</template>
<script>
import ProjectList from './components/ProjectList'
import ProjectAboutBox from './components/ProjectAboutBox'
export default {
name: 'App',
created() {
console.dir(this.$route.params)
},
components: {
ProjectList,
ProjectAboutBox
}
}
</script>
However, when I write this.$route.params to the console, I see that it is an empty object.
I didn't see anyone who encountered something similar, so my guess is that I'm missing something very basic, but I can't figure out exactly what it is.
In addition, if I console.dir(this.$route) I'm seeing that fullPath is "/", even though I'm accessing http://localhost:8080/project/kljkjkj/
EDIT:
I have also found that when I create a <router-link> that leads to the address I want to parse, then clicking on it make the whole thing work, just accessing it directly by typing the address in the address bar fails
I come across a similar problem.
When manually enter url or refresh the browser, the $route object is not populated.
After some investigation, I found that if a lazy-loading route is matched:
For components outside 'router-view':
the $route object is not being populated even in the 'mounted' hook, but is populated later in the rendering process.
For components inside 'router-view':
the $route object is populated and available immediately
My fix is to use 'computed' property instead of 'data' when try to access variable inside the $route object.
Version:
"vue": "^2.6.11",
"vue-router": "^3.2.0"
Node: Changing the mode from 'hash' to 'history' doesn't help in my case.
Default vue-router is hash mode. You can try visit http://localhost:8080/#/project/kljkjkj/
You can change to history mode
const router = new VueRouter({
mode: 'history',
routes: [{ path: "/project/:project_id", component: App }]
});
Demo: https://codesandbox.io/s/p9v3172x6j (try to change url to https://p9v3172x6j.codesandbox.io/project/1234)
when in <template>you don't need to refer this.
have you tried:
<template>
<div id="app">
<img src="./assets/logo.png">
<div id="center_bar">
oh: {{$route.params.project_id}}
</div>
</div>
</template>
?
Also, I see that you are not using a <router-view>:
https://router.vuejs.org/api/#router-view