Vue Router - Paths being concatenated multiple times - javascript

I am facing problems with the Vue Router and I have no idea what is causing this...
When my application loads it inserts the page path twice.
Example:
If I access the path http://localhost:8080/painel it will be shown in the browser the following path: http://localhost:8080/painel/painel
If I refresh the page the path will be added one more time, going like this: http://localhost:8080/painel/painel/painel
MY files:
/src/main.js
import Vue from 'vue'
import localforage from 'localforage'
import Notifications from 'vue-notification'
import App from './App'
import store from './store'
import router from './router'
import bus from './support/bus'
import http from './support/http'
Vue.config.productionTip = true
window._ = require('lodash')
localforage.config({
driver: localforage.LOCALSTORAGE,
storeName: 'invenio-center'
})
store.dispatch('auth/setToken').then(() => {
store.dispatch('auth/fetchSystemData').catch(() => {
store.dispatch('auth/clearAuth')
})
}).catch(() => {
store.dispatch('auth/clearAuth')
})
Vue.use(Notifications)
Vue.use(bus)
Vue.use(http)
new Vue({
el: '#app',
router,
store,
components: {App},
template: '<App/>'
})
/src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store'
import Login from '../pages/Login'
import Panel from '../pages/Panel'
import PanelIndex from '../pages/panel/Index'
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'login',
component: Login,
meta: {
visitor: true
}
},
{
path: 'painel',
component: Panel,
meta: {
auth: true
},
children: [
{
path: '/',
name: 'panel.index',
component: PanelIndex
},
{
path: 'idr',
name: 'panel.idr',
component: PanelIndex
}
]
},
{
path: "*",
redirect: {
name: 'panel.index'
},
component: PanelIndex
}
]
})
router.beforeEach(
(to, from, next) => {
store.dispatch('auth/setToken').then(() => {
if(to.meta.visitor){
next({
name: 'panel.index'
});
return;
}
next();
}).catch(() => {
if(to.meta.auth){
next({
name: 'login'
});
return;
}
next();
})
}
)
export default router
/src/pages/Panel.vue
<template>
<div class="panel-container">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Panel',
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.panel-container {
}
</style>
/src/pages/panel/Index.vue
<template>
<div class="index-container">index</div>
</template>
<script>
export default {
name: 'PanelIndex',
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.index-container {
}
</style>

try this, add / before path: '/painel', and do that for other components.
/ is used to distinct from relative path.

Related

How to solve vue-router Uncaught TypeError?

I am trying to upgrade my project from vue 2 to vue 3. But constantly I getting errors.
This is my new console error:
vue-router.mjs:3499 Uncaught TypeError: Cannot read properties of undefined (reading 'location')
And this is line 3499:
push(routerHistory.location).catch(err => {
if ((process.env.NODE_ENV !== 'production'))
warn('Unexpected error when starting the router:', err);
});
The file is in node_modules (front/node_modules/vue-router/dist/vue-router.mjs)
How can I fix it?
I am using: "vue-router": "^4.1.2",
main.js:
import { library } from '#fortawesome/fontawesome-svg-core';
import {faSpinner} from '#fortawesome/free-solid-svg-icons';
import SortedTablePlugin from 'vue-sorted-table/src';
import { FontAwesomeIcon, FontAwesomeLayers } from '#fortawesome/vue-fontawesome';
import { BootstrapVue3 } from 'bootstrap-vue-3';
import { createApp, h } from 'vue';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
library.add(
faSpinner,
);
const app = createApp({
render: () => h(App),
});
app.use(router);
app.use(BootstrapVue3);
app.use(SortedTablePlugin);
app.component('font-awesome-icon', FontAwesomeIcon);
app.component('font-awesome-layers', FontAwesomeLayers);
app.mount('#app');
router/index.js
// import Vue from 'vue';
import { createRouter } from 'vue-router';
import FormStep from '#/components/FormStep.vue';
import DualTable from '#/components/DualTable.vue';
import ListTable from '#/components/ListTable.vue';
import CaptureScreen from '#/components/CaptureScreen.vue';
import StageScreen from '#/components/StageScreen.vue';
import TopScreenConfig from '#/components/TopScreenConfig.vue';
import EmailCapture from '#/components/EmailCapture.vue';
import store from '#/store';
// Vue.use(VueRouter);
const routes = [
{
path: '/form/:form/step-:step',
name: 'FormStep',
component: FormStep,
}, {
path: '/form/:form/step-:step/:related',
component: FormStep,
}, {
path: '',
name: 'ListTable',
component: ListTable,
}, {
path: '/:status.html',
component: ListTable,
}, {
path: '/personal/',
component: ListTable,
}, {
path: '/personal/:status.html',
component: ListTable,
}, {
path: '/aggregator/',
component: ListTable,
}, {
path: '/aggregator/:status.html',
component: ListTable,
}, {
path: '/config/case_and_process_types.html',
component: DualTable,
}, {
path: '/run_stage/:id/',
name: 'StageScreen',
component: StageScreen,
}, {
path: '/capture/:id/',
name: 'CaptureScreen',
component: CaptureScreen,
}, {
path: '/capture_from_email/:email/:id/',
name: 'EmailCaptureScreen',
component: EmailCapture,
}, {
path: '/config/screens/:id.html',
name: 'ScreenConfig',
component: TopScreenConfig,
}, {
path: '/config/:model/',
name: 'ConfigList',
component: ListTable,
}, {
path: '/emails/',
name: 'Emails',
component: ListTable,
},
];
const router = createRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth) && !store.state.user.isAuthenticated) {
next('/login/');
return;
}
next();
});
export default router;
Is it about Vue.use(VueRouter); ?
You need to replace the mode: 'history' with history: createWebHistory() property, as the mode property is deprecated in version 4.
For more resources.
https://router.vuejs.org/guide/migration/index.html#new-history-option-to-replace-mode
This is a resource for migration from Vue 2 to Vue 3
https://router.vuejs.org/guide/migration/index.html
The router instance should be created in this way :
import { createRouter,createWebHashHistory } from 'vue-router';
....
const router = createRouter({
history: createWebHashHistory(),
base: process.env.BASE_URL,
routes,
});

Transition between views

I am a beginner in Vue (a few hours) and I have trouble switching to the next view after pressing the button.
login: function () - In strict mode code, functions can only be declared at top level or inside a block. (10: 9)
Can anyone tell me why this is happening?
Login.vue
<template>
<div>
<button v-on:click="login">
</button>
</div>
</template>
<script>
methods: {
login: function () {
this.$router.push('/home')
}
}
</script>
rouetr.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '#/components/Home.vue';
import Login from '#/components/Login.vue'
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/login',
name: 'Login',
component: Login
},
];
const router = new VueRouter({
routes,
});
export default router;
I think that it's a linter error, try to declare your function like this:
<script>
methods: {
login () {
this.$router.push('/home')
}
}
</script>
I chcange this and it wokrs
<script>
export default {
name:"App",
methods: {
next() {
this.$router.push({ name: 'Home' })
console.log(this)
}
}
}
</script>

VueJS | How can i get url parameters in vue.js?

Hi I'm making my own websites. and i'm newbie vue.js
I'm trying to get parameters to url.
I've been trying to any method. but not works.
Here is a url. -> example.com:8080/login
in this page, there's a button to register.
All i want is when i give url parameter(example.com:8080/login?id=hello&pw=1234), in login.vue, insert value -> user_id = hello, user_pw = 1234 and going back to exapmle.com:/8080
i'm trying to using vue.router. but it not works.
the error is
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup!
and this is /router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '../views/Main.vue'
import Login from '../views/Login.vue'
import Intro from '../views/Intro.vue'
import Info from '../views/Info.vue'
import Setting from '../views/Setting.vue'
import store from '../store'
import user_id from '../views/Login.vue'
import user_pw from '../views/Login.vue'
Vue.use(VueRouter)
const routes = [{
path: '/',
redirect: '/main',
},
{
path: '/login',
name: 'login',
component: Login,
},
{
path: '/signup',
name: '/signup',
component: SignUp
},
{
path: '/main',
component: Main,
beforeEnter(to, from, next) {
if (store.state.accessToken) {
next();
} else {
next('/login');
}
},
children: [{
path: '',
name: 'intro',
component: Intro,
},
{
path: '/info',
name: 'info',
component: Info,
},
{
path: '/setting',
name: 'setting',
component: Setting,
},
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: Login
});
var myApp = new Vue({
router,
el: '#app',
mounted: function() {
let parameters;
parameters = this.$route.query
console.log(parameters)
user_id = this.$route.query.id
user_pw = this.$route.query.pw
}
})
export default router
and this is part of login.vue
export default {
name: "test",
function() {
return {
id: "",
pw: "",
};
},
methods: {
test() {
axios.post("/login", {
id: this.userId,
pw: this.password
})
.then(function(response) {
if(response.data.code === 200) {
}
})
},
mounted : function() {
this.load();
}
}
i don't know what is wrong in my code.
my explain is too bad. sorry. but i'm trying to do my best
You are assigning routes to the Login component.
Replace
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: Login
});
with
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
});
"Hello world" example (Maybe it will be helpful). Click on the link to get utm_source:
const User = {
template: `<div><b>User:</b> {{ this.$route.params.id }} | <b>utm_source:</b>
{{this.$router.currentRoute.query['utm_source']}}</div>`
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
const app = new Vue({ router }).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<nav>
<router-link to="/user/foo?utm_source=facebook">Click her to see the utm_source=facebook of /user/foo?utm_source=facebook</router-link>
</nav>
<router-view></router-view>
</div>

My global Components are not available

I am new to vuex so i might have only a really dumb mistake.
I am trying to make a reactive Router, for that i used the store from vuex and since i have multiple Components i used a selfwritten Plugin to make them all global. My problem is that the store, where all the routes are saved,and all other components dont have access to the components i set global. I get the following Errormessage:
Uncaught ReferenceError: Home is not defined
my Plugin to make the components global
componentPlugin.js:
import List from "./components/List.vue";
import MainMenu from "./components/MainMenu.vue";
import Test from "./views/Test.vue";
import About from "./views/About.vue";
import Menu from "./views/Menu.vue";
import Home from "./views/Home.vue";
export default {
install(Vue) {
Vue.component("List", List);
Vue.component("MainMenu", MainMenu);
Vue.component("Test", Test);
Vue.component("About", About);
Vue.component("Menu", Menu);
Vue.component("Home", Home);
}
};
my store.js:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
projects: [{ id: 0, title: "Create new Project", compRate: 0 }],
globalid: 1,
projectname: "",
routes: [
{
path: "/home",
name: "home",
component: Home
},
{
path: "/about",
name: "about",
component: About
},
{
path: "/menu",
name: "menu",
component: Menu
}
],
reloaded: 0
},
mutations: {
newProject: (state, project) => {
state.projects.push({
id: project.id,
title: project.title,
compRate: project.compRate
});
},
delProject: (state, id) => {
state.projects.forEach(e => {
if (id === e.id) {
state.projects.splice(state.projects.indexOf(e), 1);
}
});
},
newName: (state, name) => {
state.projectname = name;
},
newRoute: state => {
state.reloaded++;
}
},
actions: {
newProject: ({ commit, state }, project) => {
commit("newProject", {
id: state.globalid,
title: project.title,
compRate: project.compRate
});
state.globalid++;
},
delProject: ({ commit }, id) => {
commit("delProject", id);
},
newRoute: ({ commit }) => {
commit("newRoute");
}
},
getters: {
getProjectNumber(state) {
return state.projects.length;
},
getReloaded(state) {
return state.reloaded;
}
}
});
My main.js:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
import componentPlugin from "./componentPlugin.js";
Vue.use(componentPlugin);
import "./registerServiceWorker.js";
import App from "./App.vue";
import router from "./router.js";
import store from "./store.js";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
Vue.use(BootstrapVue);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
The storePlugin is just to make the store global
storePlugin:
import store from "./store";
export default {
store,
install(Vue) {
Vue.prototype.$myStore = store;
}
};
I am using Vue v2.5.17 and vue-router 2.0.
If you need more information, just ask but im pretty sure that this is all that matters.
When you call
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
in main.js your Vue instance doesn't know about the componentPlugin and what it does because it's called after storePlugin (in storePlugin you import the store so there is where I suspect you get the ReferenceError)
Try this:
main.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import componentPlugin from "./componentPlugin.js";
Vue.use(componentPlugin);
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
import "./registerServiceWorker.js";
import App from "./App.vue";
import router from "./router.js";
import store from "./store.js";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
Vue.use(BootstrapVue);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
projects: [{ id: 0, title: "Create new Project", compRate: 0 }],
globalid: 1,
projectname: "",
routes: [
{
path: "/home",
name: "home",
component: Vue.component('Home')
},
{
path: "/about",
name: "about",
component: Vue.component('About')
},
{
path: "/menu",
name: "menu",
component: Vue.component('Menu')
}
],
reloaded: 0
},
mutations: {
newProject: (state, project) => {
state.projects.push({
id: project.id,
title: project.title,
compRate: project.compRate
});
},
delProject: (state, id) => {
state.projects.forEach(e => {
if (id === e.id) {
state.projects.splice(state.projects.indexOf(e), 1);
}
});
},
newName: (state, name) => {
state.projectname = name;
},
newRoute: state => {
state.reloaded++;
}
},
actions: {
newProject: ({ commit, state }, project) => {
commit("newProject", {
id: state.globalid,
title: project.title,
compRate: project.compRate
});
state.globalid++;
},
delProject: ({ commit }, id) => {
commit("delProject", id);
},
newRoute: ({ commit }) => {
commit("newRoute");
}
},
getters: {
getProjectNumber(state) {
return state.projects.length;
},
getReloaded(state) {
return state.reloaded;
}
}
});
If you want to use the router in vuex I recommend vuex-router-sync

Vue / vue-router scoping

import ExpenseView from './path'
import template from './path'
const MainComponent = new Vue({
el: '#app',
data: {
expense: [{ description: 'expense description', amount: 14.99, _id: 'l;dkfjg;ladfjg;klafjg;l' }],
},
router: new VueRouter({
routes: [
{ path: '/dash', component: ExpenseView, props: { default: true, expenses: MainComponent.expense } },
]
}),
template,
created() {...},
methods: {...},
computed: {...}
})
My goal is to have the router listen to the data in MainComponent but there are scoping issues - MainComponent is not defined.
Is there a way to get the router listening to the data in MainComponent with the way this is structured?
You can see the following example
//you can try the following code
//index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import RSSFeed from '#/components/RSSFeed.vue'
export default new Router({
routes: [
{
path: '/rss-feed',
name: 'RSSFeed',
component: RSSFeed,
props: { authorName: 'Robert' }
},
]
})
//RSSFeed.vue
<template>
<ol id="feed">
{{authorName}}
</ol>
</template>
<script>
import Post from './Post'
export default {
props: ['authorName'],
data () {
return {
items: [
{
"title":"Vuejs Nodejs",
"pubDate":"20-07-2018",
"description":"Leading vuejs nodejs",
"link":"https://hoanguyenit.com"
}
],
errors: []
}
}
}
</script>
Example
//in router
const router = new VueRouter({
routes: [
{ path: 'YOUR__PATH', component: Home, props: { authorName: 'Robert' } }
]
})
//in Home.vue
//And inside the <Home /> component,
var Home = Vue.extend({
props: ['authorName'],
template: '<p>Hey, {{ authorName }}</p>'
});

Categories

Resources