Vue Layout
by darkylmnx
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<div id="app"></div>
<script id="t-app" type="text/template">
<div id="app">
<component :is="layout">
<router-view/>
</component>
</div>
</script>
<script id="default-layout" type="text/template">
<div>
<nav-bar />
<div class="container section">
<div class="columns">
<div class="column is-8">
<slot />
</div>
<div class="column is-4">
<side-bar />
</div>
</div>
</div>
<footer-bar />
</div>
</script>
<script id="no-sidebar-layout" type="text/template">
<div>
<nav-bar />
<div class="container">
<slot />
</div>
<footer-bar />
</div>
</script>
<script id="nav-bar" type="text/template">
<nav class="navbar is-light">
<div class="navbar-brand">
<div class="navbar-item" href="/">
Vue multi layouts
</div>
<a class="navbar-burger" @click="open = !open">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div class="navbar-menu" :class="{'is-active': open}">
<div class="navbar-start">
<div class="navbar-item">
<router-link class="button is-primary" :to="{name: 'about'}" @click.native="open = false">
About
</router-link>
</div>
<div class="navbar-item">
<router-link class="button is-primary" to="/" @click.native="open = false">
Posts
</router-link>
</div>
<div class="navbar-item">
<router-link class="button is-primary" :to="{name: 'photos'}" @click.native="open = false">
Photos
</router-link>
...
CSS
body {
background: #f5f5f5;
}
.navbar {
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
}
Babel + JSX
axios.defaults.baseURL = "https://jsonplaceholder.typicode.com";
const Api = {
getPosts() {
return axios.get("/posts");
},
getPost(id) {
return axios.get("/posts/" + id);
},
getPhotos() {
return axios.get("/photos");
}
};
const default_layout = "default";
// add you loayouts to the App component
const App = {
template: '#t-app',
computed: {
layout() {
return (this.$route.meta.layout || default_layout) + "-layout";
}
},
created() {
// nothing defined here (when this.$route.path is other than "/")
console.log(this.$route, this.$route.meta.layout);
},
updated() {
// something defined here whatever the this.$route.path
console.log(this.$route, this.$route.meta.layout);
}
};
const NavBar = {
template: '#nav-bar',
data() {
return {
open: false
};
}
}
const SideBar = {
template: '#sidebar'
}
const FooterBar = {
template: '#footer-bar'
}
const c404 = {
template: '#c404'
}
const About = {
template: '#about'
}
const Home = {
template: '#home',
data() {
return {
loading: true,
posts: null
};
},
created() {
Api.getPosts()
.then(response => {
this.posts = response.data;
this.loading = false;
})
.catch(() => {
alert("ERROR");
this.loading = false;
});
}
};
const Photos = {
template: '#photos',
data() {
return {
loading: true,
photos: null
};
},
created() {
Api.getPhotos()
.then(response => {
this.photos = response.data;
this.loading = false;
})
.catch(() => {
alert("ERROR");
this.loading = false;
});
}
};
const Post = {
template: '#post',
data() {
return {
page: null,
loading: true
};
},
watch: {
$route: {
immediate: true,
handler($route) {
Api.getPost($route.params.id)
.then(response => {
this.page = response.data;
...