Vue.js two different main Layouts - vue.js

I am using vue.js version 2.5.13 installed with the vue-cli using the webpack-template.
Now I would like to use the generated App.vue-template for all my public pages and another template AdminApp.vue for all my admin-routes.
My router/index.js is like this:
import Vue from 'vue'
import Router from 'vue-router'
import LandingPage from '#/components/LandingPage'
import AdminDashboard from '#/components/admin/AdminDashboard'
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'LandingPage',
component: LandingPage
},{
path: '/admin/dashboard ',
name: 'AdminDashboard',
component: AdminDashboard
}
}
My main.js is like this:
import Vue from 'vue';
import App from './App.vue';
import AdminApp from './AdminApp.vue';
import router from './router';
if (window.location.href.includes('/admin/')) {
new Vue({
el: '#app',
router,
components: {AdminApp},
template: '<AdminApp/>'
});
} else {
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>'
});
}
Now if I go to localhost:8080/#/ and then via url to localhost:8080/#/admin/dashboard the admin-panel does not use the AdminApp.vue-Template but the App.vue-Template. If I refresh this page, it works.
Do you know why? Are there some best practices for using two or more different templates for different routes?

In Brief:
You should make your layouts.For example layout1 & layout2.
Then you should define them as global component in your main.js and finally use them with v-if in your app.vue depends on your condition.
With Detail:
first in router/index.js:
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/auth/login',
name: 'login',
meta:{layout:"auth"},
component: Login
},
which first route will render with admin layout and second one render with Auth layout for example.
Now in main.js we will define layouts as component:
import Admin from './Layouts/Admin.vue'
import Auth from './Layouts/Auth.vue'
Vue.component('Admin',Admin);
Vue.component('Auth',Auth);
Then in App.vue we check meta datas that passed from routes to detect which layout needs:
<Auth v-if="this.$route.meta.layout==='auth'"/>
<Admin v-if="this.$route.meta.layout==null"/>
Ok.All thins done!
Now we have two layout.

Related

Using <router-link> with vue-custom-element

I'm very new to Vue and am trying to create a Vue app that can be embedded inside a non Vue app so I am using vue-custom-element. I am having trouble getting routing to work inside of my Vue app widget.
I have two components in my app - Schools and School.
in main.js I have this:
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import vueCustomElement from 'vue-custom-element'
import Schools from "./components/Schools";
import School from "./components/Schools";
Vue.use(vueCustomElement);
const router = new VueRouter({
routes: [
{ path: '/', component: Schools },
{ path: '/school', component: School },
]
})
App.router = router;
Vue.customElement('schools-widget', App)
and then in my schools component (Schools.vue) I have
<router-link to="/school">School</router-link>
which I was hoping would link me from my Schools component to my School component.
But I get the error
Unknown custom element: <router-link> - did you register the component correctly?
What am I doing wrong?
You should inject the router to the component like that:
Vue.customElement('schools-widget', {
router,
render: h => h(App)
});
Update 1:
Just found out that you forgot to install the Vue router plugin:
Vue.use(VueRouter)
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import Schools from "./components/Schools";
import School from "./components/Schools";
const router = new VueRouter({
routes: [
{ path: '/', component: Schools },
{ path: '/school', component: School },
]
})
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
I think your code should be like this.

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>

Can't see named routes

I'm sure i'm doing something stupid, but i just can't get this to work.
I defined routes in a separate js file, imported that into a newly created router, that i mounted in vue.
In the vue devtools i do see my named routes, but where the RouterView is in the vue devtools, the html shows
Routes.js:
import Home from '#/Views/Home.vue';
import NewProefwerk from '#/Views/NewProefwerk.vue';
const routes = [
{
path: '/',
name: 'home',
Component: Home
},
{
path: '/Nieuw',
name: 'new',
Component: NewProefwerk
}
];
export default routes;
main.js:
import VueRouter from 'vue-router';
import routes from '#/Routes'
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
base: '/',
routes
})
new Vue({
router,
render: h => h(App)
}).$mount('#app');
App.vue:
<template>
<div id="app">
<Navigation></Navigation>
<router-view></router-view>
</div>
</template>
<script>
import Navigation from '#/components/Navigation.vue';
export default {
name: 'app',
components: {
Navigation
}
};
</script>
Try to change Component to component.

vue components registration and routes

I want to use routing in my vue project, but don't register many components globally, I am having trouble here.
My project uses vue-cli and vue-router
My project idea is to register these subcomponents only in the parent component that uses the corresponding subcomponent, but I want to use routing to control the presentation of these components.
My code is as follows
Main.js
import Vue from "vue";
import App from "./App";
import VueRouter from 'vue-router'
import test from "./components/test.vue"
Vue.use(VueRouter)
Vue.config.productionTip = false;
const routes = [
{
path: '/test', component: test,
}
]
const router = new VueRouter({routes: routes});
new Vue({
router,
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<main-layout>
<router-view></router-view>
</main-layout>
</div>
</template>
<script>
import MainLayout from "./components/MainLayout.vue"
import test from "./components/test.vue"
export default {
components: {
"main-layout": MainLayout,
"test": test
},
name : "app",
data(){
return {
collapsed: false,
}
},
}
</script>
Just like the code above, I have to register every component that needs to be managed by routing in main.js and app.vue. These are cumbersome and the code is not beautiful. Is there any way or plugin to solve this problem?
You can move all the routing code to a different folder (possibly named router).
Inside the folder you can have a file called index.js that builds the router and move individual routing components to different files.
Each router component should only return router information and not a router object.
You'll still need to import individual vue components, but they'll be scattered across multiple files. This should make things tidier.
In your main.js will need to import the router, something similar to this
import router from './router'
....
Vue.use({
router
})
This is a possible folder structure for your router:
This is part of router/index.js that shows how to use routes defined in other files
import Vue from 'vue'
import Router from 'vue-router'
import API from '#/api'
import DashboardRoutes from './dashboard'
import CustomerRoutes from './customer'
import MaintenanceRoutes from './maintenance'
import DashboardStudioRoutes from './studio'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/api',
name: 'Api',
component: Api
},
DashboardStudioRoutes,
DashboardRoutes,
CustomerRoutes,
MaintenanceRoutes,
{
path: '*',
name: '404',
component: NotFound
},
],
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
})

vue 2.0 and vue-router 2.0 build SPA, router-view did not update

Build A Single page app with vue 2 and vue-router 2 and vuex 2, but do not update
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
sync(store, router)
new Vue({
router,
store,
...App
}).$mount('#app')
/src/router/index.js
import Vue from 'vue'
import routes from './routes'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes
})
export default router
/src/router/routes.js
import loader from './loader'
const routes = [
{ path: '/index', name: 'index', component: (r) => require(['./../views/index.vue'], r) }
]
export default routes
/src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {}
})
export default store
/src/view/index.vue
<template>
<div>
<h1>Hello index</h1>
</div>
</template>
<script>
import loader from './../../../router/loader'
export default {
name: 'index',
created () {
console.log('This is index')
}
}
</script>
/src/App.vue
<template>
<div id="app">
<router-link :to="'index'">index</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
mounted () {
console.log('Hello App')
}
}
</script>
I do not know what's wrong with the code, the <router-view> do not update when I change the route.
I think your app is not properly initialized yet. You are starting your app as follows:
new Vue({
router,
store,
...App
}).$mount('#app')
You have the spread operator ...App, which is not necessary - it is used to convert array items to function args, and not correct in this context. Instead you should use the render function as provided in webpack template :
/* eslint-disable-line no-new */
new Vue({
el: "#app",
store,
router,
render: h => h(App)
})
Also you have attempted to import loader in routes and index, which is not necessary if you are using vue-cli.
Maybe you can start with the webpack template as base and slowly add functionality one step at a time: start with route definitions and your route components, ensure that everything works, and finally add vuex.
$mount('#app') is fine, I think the problem is your routes.js
Try this instead:
import Index from './../views/index.vue'
const routes = [
{ path: '/index', name: 'index', component: Index }
]
And here is a working webpack template which is already configured vue-router and vuex properly, you can initialize this template via vue-cli, for your reference: https://github.com/CodinCat/vue-webpack-plus