Vuejs version with Children
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.26/vue.js"></script>
<div id="main">
<p-menu></p-menu>
<component :is="page" :transition="transitionName"></component>
</div>
<template id="pMenu">
<div class="menu">
<ul>
<li v-bind:class="this.page==item ?'focused':''" v-for="item in items" v-on:click="click(item)">
{{item}}
</li>
</ul>
</div>
</template>
<template id="container">
<div class="container">
<slot></slot>
</div>
</template>
<template id="flip">
<div class="flipContainer" v-bind:class="{ 'flip': isFlipped}">
<div class="flipIcon" v-on:click="flip">FL</div>
<div class="flipped upper">
<slot></slot>
</div>
<div class="flipped lower container-fluid">
<h3>Parametros:</h3>
<form role="form" onsubmit={ flip2 }>
<div class="form-group">
<label for="text">TĂtulo:</label>
<input type="text" class="form-control" id="text" placeholder="Enter title"></input>
</div>
<button type="submit" v-on:click="flip" class="btn btn-primary">Guardar</button>
</form>
</div>
</template>
<template id="map">
<div class="fullsize map">
<h5>MAP</h5>
</div>
</template>
<template id="graph">
<div class="fullsize graph">
<h5>GRAPH</h5>
</div>
</template>
<!-- PAGES -->
<template id="page1">
<div class="page">
<container class="container p_lt" style='width:40%;height:60%'>
<flip>
<graph></graph>
</flip>
</container>
<container class="container p_rt"...
CSS
html,
body,
#main {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background: #888;
font-family: Arial;
}
/* donde introducimos las paginas cargadas */
.page {
position: fixed;
width: 100%;
top: 60px;
bottom: 0px;
box-sizing: border-box;
display: block;
width: 100%;
padding: 2px;
}
.graph {
display: block;
background: #ddd;
}
.table {
display: block;
background: lightgray;
}
.map {
display: block;
background: #eee;
}
.container {
box-sizing: border-box;
display: block;
float: left;
padding: 2px;
}
.fullsize {
box-sizing: border-box;
height: 100%;
width: 100%;
padding: 2px;
}
/*** MENU ***/
.menu {
position: fixed;
height: 60px;
width: 100%;
top: 0px;
}
.menu ul {
list-style: none;
display: inline-block;
float: left;
margin-top: 10px;
}
.menu ul li {
display: inline-block;
padding: 10px 20px;
cursor: pointer;
background-color: #eee;
color: #7B8585;
transition: 0.3s;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.menu ul li:hover {
background-color: #beecea;
}
.menu ul li.focused {
color: #fff;
background-color: #41c7c2;
}
.menu p {
padding-top: 12px;
font-size: 12px;
color: white;
float: left;
margin-left: 20px;
font-size: 20px;
font-family: Verdana, Geneva, sans-serif;
}
/* http://davidwalsh.name/css-flip */
.flipContainer {
position: relative;
height: 100%;
width: 100%;
margin: 0 auto;
display: block;
}
.flipContainer > div.flipped {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #463;
transition: 0.6s ease-in-out;
}
.flipContainer > div.lower {
background: #fff;
backface-visibility: hidden;
transform: perspective(11800px) rotateY(180deg);
}
.flipContainer > div.upper {
backface-visibility: hidden;
transform: perspective(11800px)...
JavaScript
///////// pMenu //////////
var pMenu = Vue.extend({
template: '#pMenu',
data: function() {
return {
page: 'page1',
items: ['page1', "page2", 'page3']
}
},
methods: {
click: function(item) {
var isR = this.items.indexOf(item) > this.items.indexOf(this.page);
this.page = item;
vv.transitionName = isR ? 'pageL' : 'pageR';
vv.page = item;
},
isFocused: function(item) {
return item == this.page ? 'focused' : ''
}
}
})
Vue.component('p-menu', pMenu);
/////////// CONTAINER ///////////////
var container = Vue.extend({
template: '#container'
})
Vue.component('container', container);
/////////// FLIP ///////////////
var flip = Vue.extend({
template: '#flip',
data: function() {
return {
isFlipped: false
}
},
methods: {
flip: function(event) {
this.isFlipped = !this.isFlipped;
event.preventDefault();
}
}
})
Vue.component('flip', flip);
/////////// MAP ///////////////
var map = Vue.extend({
template: '#map'
})
Vue.component('map', map);
/////////// GRAPH ///////////////
var graph = Vue.extend({
template: '#graph',
ready: function() {
addPIE(this.$el);
}
})
Vue.component('graph', graph);
/////////// PAGE 1 ///////////////
var page1 = Vue.extend({
template: '#page1'
})
Vue.component('page1', page1);
/////////// PAGE 2 ///////////////
var page2 = Vue.extend({
template: '#page2'
})
Vue.component('page2', page2);
/////////// PAGE 3 ///////////////
var page3 = Vue.extend({
template: '#page3'
})
Vue.component('page3', page3);
///////////// MAIN //////////////
var vv = new Vue({
el: '#main',
data: {
page: 'page1',
transitionName: 'pageL'
},
computed: {},
methods: {}
})
/////////// AUX FUNCTIONS //////////////
//WHITH PIE
function addPIE(identificador) {
// Build the chart
$(identificador).highcharts({
chart: {
plotBackgroundColor: 'rgba(0,0,0,0)',
backgroundColor: 'rgba(0,0,0,0)',
...