Problem with router-view duplicating the components - vue.js

Recently changed from laravel routing to Vue Router. Whenever I'd insert the <router-view></router-view> in any part of the file below, it'll duplicate the component which the router routes to (i.e. it will duplicate the div part of the component and insert it in the sidebar.vue file) .
For demonstration of the problem: vs
SideBar.vue file is
<template>
<aside class="container_sidebar">
<nav id="sidebar">
<ul class="list-unstyled components">
<li class="active">
<router-link to="/nghome">Home</router-link>
</li>
<li>
<router-link to="/ngsongs">All Songs</router-link>
</li>
<li>
<router-link to="/ngalbums">Albums</router-link>
</li>
<li>
<router-link to="/ngartists">Artists</router-link>
</li>
</ul>
</nav>
</aside>
</template>
My Router.js file is
import NightingaleHome from "./components/NightingaleHome";
import NightingaleSongs from "./components/NightingaleSongs";
import NightingaleArtists from "./components/NightingaleArtists";
import NightingaleAlbum from "./components/NightingaleAlbum";
import MusicUpload from "./components/MusicUpload";
export const routes = [{
path: "/home",
component: NightingaleHome,
name: "home",
},
{
path: "/ngsongs",
component: NightingaleSongs,
name: "All Songs",
},
{
path: "/ngartists",
component: NightingaleArtists,
name: "All Artists",
},
{
path: "/ngalbums",
component: NightingaleAlbum,
name: "All Album",
},
{
path: "/fileupload",
component: MusicUpload,
name: "Music File Upload",
},
];
And my App.js file is
require('./bootstrap');
import { routes } from "./router";
import VueRouter from "vue-router";
import Vue from "vue";
import Vuesax from 'vuesax';
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue';
// Import Bootstrap an BootstrapVue CSS files (order is important)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
import 'vuesax/dist/vuesax.css' //Vuesax styles
Vue.use(Vuesax, {
// options here
})
window.Vue = require('vue').default;
Vue.component('music-player', require('./components/MusicPlayer.vue').default);
Vue.component('music-upload', require('./components/MusicUpload.vue').default);
Vue.component('upload-progress', require('./components/UploadProgress.vue').default);
Vue.component('nightingale-songs', require('./components/NightingaleSongs.vue').default);
Vue.component('nightingale-album', require('./components/NightingaleAlbum.vue').default);
Vue.component('nightingale-artist', require('./components/NightingaleArtists.vue').default);
Vue.component('side-bar', require('./components/SideBar.vue').default);
Vue.component('edit-songs', require('./components/EditSongs.vue').default);
Vue.component('nightingale-home', require('./components/NightingaleHome.vue').default);
Vue.use(VueRouter);
let router = new VueRouter({
mode: 'history',
routes
});
const app = new Vue({
el: '#app',
router,
});
I don't have App.vue file because currently I don't need it. Any solutions?

I don't know if there help you but for similar issue, I delete the root path in my router file ( path : "/" component: App).
I think the nativ root is already charged so you don't have to built-it.

Related

Vue3 Router duplicated component

I'm creating an app using Vue3js and vue-router.
When the app is created, I get my first component duplicated.
My App.vue component is this:
<template>
<div class="container-fluid">
<nav class="navbar navbar-expand-md fixed-top">
<div class="menu-izq">
<router-link id="logo" class="menu-item" to="/">COVELESS</router-link>
<router-link class="menu-item" v-if="!this.userLogged" to="/login">Login</router-link>
<router-link class="menu-item" v-if="this.userLogged" to="/canvas">Canvas</router-link>
<router-link class="menu-item" v-if="this.userLogged" to="/dashboard">Dashboard</router-link>
</div>
<div class="menu-dcha">
<router-link class="menu-item" v-if="this.userLogged" v-on:click="vaciarStorage()" to="/login">Logout
</router-link>
</div>
</nav>
<router-view></router-view>
</div>
My router.js file is this
import { createRouter, createWebHistory } from
'vue-router'
import LoginMenu from './components/LoginMenu.vue'
import AllElement from './components/AllElement.vue'
import Dashboard from './components/Dashboard.vue'
import App from './App.vue'
const routes = [
{
path: '/',
name: 'Home',
component: App
},
{
path: '/login',
name: 'Login',
component: LoginMenu
},
{
path: '/canvas',
name: 'Canvas',
component: AllElement
},
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard
}
]
const history = createWebHistory();
const router = createRouter({
history,
routes,
});
export default router
And my app.js file is this
import './bootstrap';
import { createApp } from 'vue/dist/vue.esm-bundler'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app');
So when the App component is mounted on #app, the navbar gets duplicated because it is mounting another App component at "/" path (I guess because it is defined at router.js like that). But if I remove the
{
path: '/',
name: 'Home',
component: App
}
route, then I'm never navigating to the index.
Here you can see both the App components.

Vue 2: vue-router-3.x not redirecting/pushing from App.vue

I made a Vue 2 web page and tried to use vue-router v3 to route to a different page. The web page is as follows:
src/App.vue: the web page opens from here
<template>
<div id="app">
<GoHere/>
</div>
</template>
<script>
import GoHere from './views/gohere/GoHere.vue'
export default {
name: 'App',
components: {
GoHere
}
}
</script>
src/main.js:
import Vue from 'vue'
import App from './App.vue'
import router from "./router/router"
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
}).$mount('#app')
src/views/gohere/GoHere.vue: the page from which the issue arises
<template>
<div>
<v-btn #click="goHere()">
Go Here
</v-btn>
</div>
</template>
<script>
export default {
name: "GoHere",
methods: {
goHere() {
this.$router.push("/menu")
}
}
}
</script>
src/views/menu/Menu.vue: the page to redirect to
<template>
<div>
Menu
</div>
</template>
<script>
export default {
name: "Menu",
}
</script>
src/router/router.js: the router file
import Vue from 'vue'
import VueRouter from 'vue-router'
import GoHere from '../views/gohere/GoHere'
import Menu from '../views/menu/Menu'
Vue.use(VueRouter)
const routes = [
{ path: '/', name: "gohere", component: GoHere},
{ path: '/menu', name: "menu", component: Menu}
]
const router = new VueRouter({
routes
})
export default router
When I clicked on the button in GoHere.vue, the URL changes into "http://localhost:8080/#/menu" but the content does not change into the content for Menu.vue. How can the problem be solved?
The component from the current route will automatically render in <router-view></router-view>
App.vue:
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
Check the docs

Vue-router: do i need to define the default route for vue-router

Experimenting with vue-router, when i click on <router-link to="/about">Go to About</router-link> it doesnt redirect me to anywhere so for example: if i was on localhost:8080/#/ and i click the Go to About button, i still remain on localhost:8080/#/. Also if i change the url directly to localhost:8080/#/about nothing happens (ie no change to the website as if i am still on localhost:8080/#/)
The code:
/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{
path: '/about',
component: () => {
import ('../views/About.vue');
}
}
]
const router = new VueRouter({
routes
})
export default router;
./App.vue
<template>
<div>
<div id='nav'>
<router-link to="/about">Go to Foo</router-link>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {
//
},
data: () => ({
//
}),
};
</script>
./views/About.vue
<template>
<p>Testing out vue-routes</p>
</template>
./main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import store from './store';
import router from './router';
Vue.config.productionTip = false;
new Vue({
vuetify,
store,
router,
render: h => h(App)
}).$mount('#app')
I tried running the following code. it gave no error on serving. (I am also using vuetify and vuex but i dont think that is the problem?)
EDIT
I have edited the code such that it works by creating another vue app and using the default that vue has provided with but i cant seem to understand why the edited code works and why the previous code ^^ above didnt. It seems like the reason was that the default localhost:8080/#/ needs to have its own route in ./App.vue as well and is not there by default? can someone confirm this (can't seem to find something like this explanation online?)
Revised working code:
./App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
</template>
./views/Home.vue
<template>
<h1>This is the home page</h1>
</template>
<script>
export default {
name: 'Home',
components: {
//
},
data: () => ({
//
}),
};
</script>
./main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import store from './store';
import router from './router';
Vue.config.productionTip = false;
new Vue({
vuetify,
store,
router,
render: h => h(App)
}).$mount('#app')
./router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router';
import Home from "../views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/about",
name: "About",
component: () =>
import("../views/About.vue")
}
];
const router = new VueRouter({
routes
})
export default router;
./views/About.vue
<template>
<p>Testing out vue-routes</p>
</template>
You need to have a <router-view/> where the routes are going to resolve.
You can read more about it here: documentation

How to proper use vue-router?

I want to exclude the h1 tag every time I go to different route in my Vue application.
Here's my app.vue:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<h1>LANDING PAGE</h1>
<router-view></router-view>
<!--Path for login.vue-->
<button #click="$router.push('/login')">LOGIN</button>
</div>
</template>
<script>
export default {
name: 'app',
}
</script>
And here's my login page, where I want only to display my design for login page only:
<template>
<div>
<h1>Login Page</h1>
</div>
</template>
<script>
export default {
name: "Login"
}
</script>
My route.js:
import Login from './components/LandingPage/Login';
import Register from './components/LandingPage/Register';
export default [
{
path: '/login', component: Login
},
{
path: '/register', component: Register
}
]
and lastly my main.js:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './routes';
import VueResource from 'vue-resource'
Vue.config.productionTip = false;
Vue.use(VueRouter);
Vue.use(VueResource);
const router = new VueRouter({
routes: Routes,
/* To remove # in the URL */
mode: 'history'
});
new Vue({
render: h => h(App),
router: router
}).$mount('#app');
I didn't include the register.vue because it's just the same with login.vue.
Conditional rendering based on the landing page url:
<h1 v-if="$route.path === '/landing-page-url'">LANDING PAGE</h1>
Actually, there are three approaches to solve your problem:
Just drop your <h1></h1> into your landing page component.
You can use conditional rendering, like Psidom answered (just changed path to name):
<h1 v-if="$route.name === 'Landing'">Landing page</h1>
You can have only one <h1></h1> in your main layout, and render current page title dynamically. Route Meta Fields come in rescue.
import Login from './components/LandingPage/Login'
import Register from './components/LandingPage/Register'
export default [
{
path: '/login',
component: Login,
meta: {
title: 'Login',
},
},
{
path: '/register',
component: Register,
meta: {
title: 'Register',
},
},
]
And then in your template:
<h1>{{ $route.meta.title }}</h1>
P.S. To navigate to another route in your template use <router-link></router-link> instead of button with click event.

Vue router link add object in the url

This is my setting:
main.js creates a vue and attaches the component App to an element in the dom
router.js sets the routs
App.vue has the router-view and a few router-links
Problem:
the link <router-link to="/admin">Admin1</router-link> works fine
the link <router-link to="{name: 'admin'}">Admin2</router-link> doesn;t work and adds to the url bar: #/{name: 'admin'}
Am I using the router in the wrong way?
Below my files in details
main.js
import Vue from 'vue'
import router from './router'
import App from './App'
new Vue({
router,
el: '#app',
components: { App },
template: '<App/>',
data: {
}
})
router.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Marketplace from '#/components/Marketplace'
import Admin from '#/components/Admin'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/marketplace',
name: 'marketplace',
component: Marketplace
},
{
path: '/admin',
name: 'admin',
component: Admin
}
]
})
App.vue
<template>
<div id="app">
<p>
<router-link to="/">Home</router-link>
<router-link to="/admin">Admin1</router-link>
<router-link to="{name: 'admin'}">Admin2</router-link>
</p>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
In order for your to="{name: admin}" to work without adding the char #, do the following inside your router config file.
Also you are supposed to use the v-bind for to="".
Use v-bind:to="{name: 'admin'}" or :to="{name: 'admin'}"
Example:
export default new Router({
mode: 'history',
// whatever you have
})
Source: https://router.vuejs.org/en/essentials/history-mode.html