VueJS router configuration not enabled - vue.js

In my VueJS project, I have configured the routing in a file "router.js".
import VueRouter from 'vue-router'
import personDetails from './components/component.vue'
Vue.use(VueRouter)
export default new VueRouter({
mode : 'history',
base : '/',
routes : [
{
path : '/:group/:id',
name : 'personDetails',
component : personDetails ,
props : true
}
]
})
In the main.js file, I enable the routing configuration like this:
import App from './App.vue'
import router from './router'
new Vue({
router,
el : '#app',
components : { App }
}).$mount('#app')
This is my App.js file:
<template>
<div id="app">
<router-view v-bind="$props" />
</div>
</template>
<script>
export default {
name: 'App',
props : ['group', 'id'],
mounted() {
console.log('Mounted App')
}
}
</script>
I run the project by running "vue-cli-service build" and "npx http-server ./dist" commands.
I notice that when I call the configured router like this - "http://localhost:8080/1234/56", I get a 404 error. However when I call the default URL "http://localhost:8080" I get a blank page, since the App is loaded without any routing parameters. I can see the console.log() statements added to main.js and App.js, but not the "personDetails" component.
I added a default router configuration, and that seems to be working.
{
path : '/',
redirect:'/456/123'
}
This default routing loads the 'personDetails' component with the path parameters mapped to 456 and 123.
Please give some tips to debug this?

This is due to mode: 'history'. More details here - HTML5 History Mode
Since our app is a single page client side app, without a proper
server configuration, the users will get a 404 error if they access
http://oursite.com/user/id directly in their browser.
To fix the issue, all you need to do is add a simple catch-all
fallback route to your server. If the URL doesn't match any static
assets, it should serve the same index.html page that your app lives
in.

You can use the fallback proxy of http-server as a catch-all redirect: npx http-server ./dist -P http://localhost:8080?

Related

How can I redirect using vue-router?

I have tried to access to others pages via url, but those pages never loads
http://localhost:8080/index
http://localhost:8080/about
This is my main.js file
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import VueRouter from 'vue-router'
Vue.config.productionTip = false
Vue.use(VueRouter)
import Index from './views/Index';
const About = { template: '<p>about page</p>' }
const routes = [
{ path: '/index', name: 'index', component: Index },
{ path: '/about', name: 'about', component: About }
]
var router = new VueRouter({
routes: routes,
mode: 'history'
})
new Vue({
router: router,
vuetify,
render: h => h(App)
}).$mount('#app')
Does anyone can help me with vue-router? i am new in this framework
Does it work if you access them like this:
http://localhost:8080/#/about
If yes, your vue-router is working in the default hash-mode. To get rid of the hash and get "normal" URLs you'll need to set it to history mode.
Edit:
As I see you're already using history mode. Do you use Vue CLI for local development? This should normally work out of the box. If not, you need to setup some redirect rules on other web servers. Please see the examples here: Example Server Configurations
Edit 2:
Can you show your App component?
I tried to reproduce your problem in a sandbox, but it works: https://codesandbox.io/s/confident-voice-zyg07
The App component here looks like this, including the router-view:
<template>
<div id="app">
<router-view id="page"/>
</div>
</template>
<script>
export default {
name: "App",
components: {}
};
</script>

Vue.js VueRouter router-link changes URL but page does not

my main.js file has the following
import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm';
import VueRouter from 'vue-router';
import EventIndex from '../src/views/EventsIndex.vue';
import EventsTable from '../src/components/EventsTable.vue'
import { routes } from '../src/router/routes';
Vue.use(TurbolinksAdapter);
Vue.use(VueRouter);
const router = new VueRouter({
routes,
mode: 'history'
});
document.addEventListener('turbolinks:load', () => {
var element = document.getElementById('vue_code');
if (element != null) {
new Vue({
el: '#vue_code',
Store,
router,
render: h => h(EventIndex)
});
My routes.js file has the following:
import Vue from "vue/dist/vue.esm";
import VueRouter from "vue-router";
import EventForm from "../components/EventForm";
Vue.use(VueRouter);
const routes = [
{
path: "/events/new",
name: "EventForm",
component: EventForm
}
];
The router-link snippet from my component file EventsTable.vue file has the following:
<template lang=haml>
...
%tbody
%tr{v-for: "event in events"}
%td
%router-link.fa.fa-pencil{to: "/events/new"}
%router-view
...
<template>
<script>
import EventForm from './EventForm';
components: {
EventForm
}
</script>
When I click on the link, i expect the page to change to the EventForm page. Instead, the url changes, but the browser window does not change. But once I reload the page, the browser jumps to the EventForm page.
Any help is appreciated. Thanks
The first line of the vue-turbolinks package states:
⚠️ If you're using vue-router or another Javascript routing library, you don't need to use Turbolinks or this adapter. Turbolinks is meant to level up the traditional request-render cycle by loading the new page in the background and this adapter makes it possible to use Vue components on pages rendered in this manner. If you've decided to use a single-page app, you already have everything you need. 🤘
You cannot use vue-router and Turbolinks together. Turbolinks handles all of your site navigation. Navigating using vue-router doesn't work because it is attempting to do a history push instead of an entire page load.
I suggest programmatically routing using the Turbolinks.visit() function instead of using vue-router. You'll need to create a new view for the EventForm page that loads your vue component.

using vue-router to redirect to different pages

I have a vue application which dose simple inserts and i am trying to use vue router to redirect to different pages for example when i load /postComponent and /userComponent they will be on separate pages not all in one page when loading the localhost:8080
app.js
<template>
<div id="app">
<router-link to="/postcomponent">post</router-link>
<router-link to="/usercomponent">user</router-link>
<router-view/>
</div>
</template>
<script>
import PostComponent from './components/postComponent';
import userComponent from './components/userComponent';
export default {
name: 'app',
components: {
PostComponent,
userComponent
}
};
</script>
routes.js
import Vue from 'vue'
import App from '/client/src/App'
import VueRouter from 'vue-router'
import postComponent from '/client/src/components/postComponent';
import userComponent from '/client/src/components/userComponent';
vue.use(VueRouter);
Vue.config.productionTip = false
const routes = [
{
path: '/postcomponent',
name: 'postcomp',
component: postComponent
},
{
path: '/usercomponent',
name: 'usercomp',
component: userComponent
},
];
new Vue({
routes,
render: h => h(App),
}).$mount('#app')
postComponent
<script>
import postService from '../postService';
export default {
name: 'postComponent',
data() {
return {
posts: [],
error: '',
topic: '',
price: '',
location: '',
provider: ''
}
},
index.js
const express = require ('express');
const bodyparser = require ('body-parser');
const cors = require ('cors');
const app = express();
app.use(bodyparser.json());
app.use(cors());
const posts = require('./api/posts');
const users = require('./api/users');
app.use('/api/posts', posts);
app.use('/api/users', users);
const port = process.env.port || 500;
app.listen(port, () => console.log(`Server started on port ${port}`));
im getting the following error
https://i.stack.imgur.com/42Ka3.png
UPDATE ** :
App.vue :
<template>
<div id="app">
<router-link to="/postcomponent">post</router-link>
<router-link to="/usercomponent">user</router-link>
<router-view/>
</div>
</template>
Inside Routes.js import statements and paths :
import PostComponent from "#/components/PostComponent";
import UserComponent from "#/components/UserComponent";
const routes = [
{
path: '/postcomponent',
name: 'postcomp',
component: PostComponent
},
{
path: '/usercomponent',
name: 'usercomp',
component: UserComponent
},
];
PostComponent :
<template>
Post Comp
</template>
<script>
export default {
name: "PostComponent"
}
</script>
User Comp :
<template>
User Comp
</template>
<script>
export default {
name: "PostComponent"
}
</script>
UPDATE * :
remove those unnecessary imports on app file
I think its better to first have a look at Vue-router at https://router.vuejs.org/
SPA stands for Single Page Application means that all of your components eventually will execute on a single *.html file. this means that in SPA, you cant just redirect your client to another url and perform another HTTP request and still be on the same Vue SPA!. because then you will probably get new html/css and javascript files to execute and render.all you can do is 1.use vue router to specify on which path, what component should render. when you describe your router using VueRouter thats exactly what you are going to do!, config your router and tells him on which path, what component you should render.
there is no way that you can redirect your client to another domain and still be on the same SPA and loads your components BUT !
as i can see in your codes there is a way to achieve what you want. there are some problems in your code but i'll show you how you can config two routes to achieve something like that.
i assume that you have those two components postComponent and userComponent ready.
first we have to import those in our routes.js :
import postComponent from 'PATH_TO_COMP';
import userComponent from 'PATH_TO_COMP';
note that you can use '#' as an alias for /src in your directory
first we have to specify two routes, for /postcomponent and /usercomponent,
we doing it by adding two objects to routes array in VueRouter, we can specify a name for our routes and we must specify a component which will render on that router,
routes : [
{path : "/postcomponent", name :"postComp", component:postComponent},
{path : "/usercomponent", name :"userComp", component:userComponent}
]
so now we have to implement our app file to say that where we want this components to render, we use empty <router-view/> tag to show that,
now everything is set, you can switch between routes using <router-link> tag like below :
<router-link to="/postcomponent" >Show me post component :)</router-link>
and you will see that when you go to http://localhost:8080/postcomponent your postComponent will render and sits on your <router-view/> !

Vue Js 2 / Vue-CLI 3 / When hosted shows empty blank page

Vue Js app working fine in dev mode, but as I upload it on the server, it simply displays a blank page. All the resources are showing up in the developer console. I am using vue-router package.
VueJs 2 / Vue-CLI-3
Below is my App.vue
<template>
<div id="app">
<m-nav/>
<router-view></router-view>
</div>
</template>
<script>
import Navbar from './components/Navbar.vue'
export default {
name: 'app',
components: {
'm-nav':Navbar
}
}
</script>
<style>
</style>
This is my main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import HomePage from './components/HomePage.vue'
import Brochure from './components/Brochure.vue'
import Register from './components/Register.vue'
Vue.config.productionTip = false
Vue.use(VueRouter);
const routes = [
{
path:'/',
component: HomePage
},
{
path:'/download',
component: Brochure
},
{
path:'/register',
component: Register
}
];
const router = new VueRouter({
routes,
mode: 'history'
});
new Vue({
router,
render: h => h(App),
}).$mount('#app');
after running npm run build, It shows a blank page, although I can see some stuff in the DOM <div id="app"></div>
http://prntscr.com/lvasvo
I am not getting, where I have made a mistake! The project is complete, but stuck on this part! :(
follow this tips:
use <%= BASE_URL %> for script and link tags which wrote on index.html
create vue.config.js in root of project and config your public path for production and development mode like:
module.exports = {
publicPath:
process.env.NODE_ENV === "production" ? "/" : "/"
}
};
just use relative path, to know more about it, read this link:
https://cli.vuejs.org/config/#publicpath
create config.vue.js
In my case the issue was in the Router.beforeEach function that I had in index.js file inside the router folder to add a route guard. I had to rewrite it after upgrading it from Vue 2 to Vue 3 to make it work.
Just encounter the same issue with vue-cli3 project.
And my main reason getting this issue is my app doesn't deploy on the root of the domain,instead on a sub-path.
There're several tricky configures:
vue.config.js (it's vue-cli3 exclusive): to set publicPath:/my-app/ ;
router.js (assuming your vue-router config file is this): to set base:/my-app/;
And beware of the history router mode:
this mode needs extra server side config, I'm using nginX, this is my config:
location /my-app {
alias /var/www/my-app;
try_files $uri /index.html last;
index index.html;
}
And beware of the different between alias and root.
this mode is not support relative path publicPath:./ in vue.config.js.

vue js two SPAs

I am building a web app with two layouts (for login page, and dashboard). Each of them are represented as SPA application, so each has router-view. The main problem is 'How to connect them and redirect from one to another?'.
I have a App.vue - check if user is authorized. if yes - redirect to Dashboard.vue, else - redirect to Login.vue. Each of them has there own router-view.
An SPA should be a single html file which serves up your app and all the routes, so the basic structure should be:
HTML
<div id="app">
</div>
<!-- bundled file -->
<script src="app.js"></script>
app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import App from './components/App.vue' // import Base component
// Import views to register with vue-router
import Login from './components/views/Login.vue'
import Dashboard from './components/views/Dashboard.vue'
const guard = function(to, from, next) {
// Check if user is logged in (you will need to write that logic)
if (userIsLoggedIn) {
next();
} else {
router.push('/login');
}
};
const routes = [{
path: '/login',
component: Login
},{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
guard(to, from, next); // Guard this route
}
}]
const router = new VueRouter({
mode: 'history', // history mode
routes
})
new Vue({
el: '#app',
router,
render: h => h(App) // mount base component
})
App.vue
<template>
<div>
<!-- Your layout -->
<!-- All views get served up here -->
<router-view></router-view>
</div>
</template>
I haven't tested that, but in this scenario every view component gets served up by App.vue which is mounted on the main vue instance. You then use the beforeEach guard to check that the user is logged in, if they are then you call next() which takes them to the route, if they are not then you redirect them to login.
vue-router has the ability to create custom guards for any route. You do not need 2 separate applications, just some safety with the routes in your router.
https://router.vuejs.org/en/advanced/navigation-guards.html
Your guard could be a function that checks for authentication.
Here's a full implementation tutorial from Auth0: https://auth0.com/blog/vuejs2-authentication-tutorial/