UNPKG

vue-golden-layout

Version:

Integration of the golden-layout to Vue

102 lines (92 loc) 3.21 kB
import { Watch, Component, Prop, Emit } from 'vue-property-decorator' import { glRow } from './gl-group' import { Vue } from './imports' import goldenLayout, {renderVNodes} from './golden.vue' //TODO: there might be a type for route function defaultTitle(route: any): string { //The last case is to warn the programmer who would have forgotten that detail return (route.meta && route.meta.title) || 'set $route.meta.title'; } const RouteComponentName = '$router-route'; goldenLayout.registerGlobalComponent(RouteComponentName, gl=> function(container, state) { gl.onGlInitialise(()=> { var comp = gl.$router.getMatchedComponents(state)[0], route = gl.$router.resolve(state).route; //TODO: comp can be a string too if('object'=== typeof comp) comp = Vue.extend(comp); var div, template = gl.$scopedSlots.route ? gl.$scopedSlots.route(route) : gl.$slots.route; if(template) { //template is a VNode div = renderVNodes(gl, container.getElement()[0], template).$el.querySelector('main'); } else { div = document.createElement('main'); container.getElement().append(div); } var parent = container.parent.parent; while(!parent.vueObject || !parent.vueObject._isVue) parent = parent.parent; if(div) new comp({el: div, parent: parent.vueObject}); else console.error('Missing <main /> tag in route-page design'); }); }); @Component() export default class glRouter extends glRow { @Prop({default: defaultTitle}) titler : (route: any)=> string @Prop({default: '/'}) emptyRoute: string get stack() { var ci = this.glObject, rv; if(!ci) return null; rv = ci.contentItems.find(x => 'stack'=== x.type); if(!rv) { ci.addChild({ type: 'stack', content: [] }, 0); rv = ci.contentItems[0]; } return rv; } @Watch('stack.vueObject.glObject') @Watch('stack.config.activeItemIndex') setPath(v) { var path; //stacks created by the users are created without an activeItemIndex if(v && 'object'=== typeof v) { //set `activeItemIndex` observed var config = v.config, aii = config.activeItemIndex; delete config.activeItemIndex; this.$set(config, 'activeItemIndex', aii); } var aci = this.stack.getActiveContentItem(); if(aci && RouteComponentName=== aci.config.componentName) { path = aci.config.componentState; } else path = this.emptyRoute; if(path != this.$route.fullPath) this.$router.replace(path); } @Watch('$route') change(route) { if(route && route.matched.length) this.onGlInitialise(()=> { var ci = this.glObject; if(ci) { var stack = this.stack; var already = stack.contentItems.find(x=> x.config.componentState.path == route.fullPath); if(already) stack.setActiveContentItem(already); else stack.addChild({ type: 'component', componentName: RouteComponentName, componentState: { path: route.fullPath }, title: this.titler(route) }); } }); } mounted() { //With immediate: true, the watch is called before $refs are initialised this.change(this.$route); } }