vue-router not rendering component, but changing url on this.$router.push

Viewed 8386

I'm trying to redirect to a Menu after pressing a button, I have followed this tutorial but it's not working,

When Pressing my button the url updates, but stays in the same view, it's also adding /#/ to my url instead of following what I coded in routes.js

I'm getting the next error on console

 Uncaught (in promise) 
NavigationDuplicated {
_name: "NavigationDuplicated", 
name: "NavigationDuplicated", 
message: "Navigating to current location ("/menu") is not allowed", stack:

When pressing the button the url turns into http://localhost:8080/#/menu instead of http://localhost:8080/menu

If I manually type the url http://localhost:8080/menu turns into this http://localhost:8080/menu/#/

Please help, I'm fairly new to vuejs

This is the structure of my project

enter image description here

main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter  from 'vue-router'
import vuetify from './plugins/vuetify'
import routes from './routes'
import 'roboto-fontface/css/roboto/roboto-fontface.css'
import '@mdi/font/css/materialdesignicons.css'

Vue.config.productionTip = false
Vue.use(VueRouter)
const router = new VueRouter({routes});

new Vue({
  render: h => h(App),
  router,
  vuetify
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <Home/>
  </div>
</template>

<script>
import Home from './views/Home.vue'
import 'material-design-icons-iconfont/dist/material-design-icons.css';

export default {
  name: 'App',

  components: {
    Home
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

my routes.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
import TraceabilityMenu from './views/TraceabilityMenu.vue'

Vue.use(VueRouter)

const routes = [
  { path: '/', component: Home, name: 'home' },
  { path: '/menu', component: TraceabilityMenu, name: 'traceability-menu' },  
  {path: '/about', component: About, name: 'about'}
]
export default routes;

My Home.vue which is the first view to load(by the App.vue)

<template>
  <v-app id="inspire">
    <v-app-bar app color="indigo" dark>
      <v-toolbar-title>Project Traceability</v-toolbar-title>
      <template>
        <v-spacer />
          <v-btn color="primary" @click="showPopupLogin()" :to="{ name: 'login'}" >Ingresar</v-btn>
      </template>

    </v-app-bar>
    <PopupLogin v-show="showLogin"/>
    <v-content>
      <v-container
        class="fill-height"
        fluid
      >
        <v-row
          align="center"
          justify="center"
        >
          <v-col class="text-center">
          </v-col>
        </v-row>
      </v-container>
    </v-content>
    <v-footer
      color="indigo"
      app
    >
    </v-footer>
  </v-app>
</template>

<script>
import PopupLogin from '@/components/PopupLogin.vue';
  export default {
    props: {
      source: String,
    },
    data: () => ({
      showLogin     : false
    }),
    components: {
        PopupLogin,
    },
    methods: {
      showPopupLogin() {
        this.showLogin = !this.showLogin
      }
    }
  }
</script>

The component PopupLogin

<template>
  <v-app id="inspire">
    <v-content>
      <v-container class="fill-height" fluid>
        <v-row align="center" justify="center">
          <v-col cols="12" sm="8" md="4">
            <v-card class="elevation-12">
              <v-toolbar color="primary" dark flat >
                <v-toolbar-title>Iniciar sesión</v-toolbar-title>
                <v-spacer />
                <v-tooltip bottom>
                </v-tooltip>
              </v-toolbar>
              <v-card-text>
                <!-- Formulario de login-->
                <v-form v-model="validForm" ref="formLogin">
                  <v-text-field 
                    required 
                    label="Usuario" 
                    :rules="nameRules" 
                    name="login" 
                    type="text" 
                    v-model="existingUser.username"/>
                  <v-text-field 
                    required 
                    id="password" 
                    prepend-icon="lock" 
                    label="Contraseña" 
                    name="password" 
                    type="password"
                    v-model="existingUser.password"/>
                </v-form>
              </v-card-text>

              <v-card-actions>
                <v-spacer/>
                <v-btn color="primary" @click="loginUser()">Ingresar</v-btn>
              </v-card-actions>
            </v-card>
          </v-col> 
        </v-row>
      </v-container>
    </v-content>
  </v-app>
</template>


<script>
  export default {
    name: 'PopupLogin',
    props: {
      source: String
    },
    data: () => ({
      validForm     : false,
      //objetos
      existingUser  : {}
    }),
    methods: {
      //Funcion que llamara al servicio de login en backend
      loginUser() {
        this.$router.push({path: '/menu'});
      }
    }
  }
</script>

TraceabilityMenu.vue the view which I'm trying to render after the press of the button Login

<template>
  <v-app id="inspire">
   <div>RENDER ME!</div>
  </v-app>
</template>

<script>
  export default {
    props: {
      source: String,
    },
    data: () => ({
      drawer: null,
    }),
  }
</script>
1 Answers

On your main.js file try changing

const router = new VueRouter({routes});

to

const router = new VueRouter({routes, mode: 'history'});

Edit: Also check if you have included the router-view tag on your root component App.vue.

Related