<template> <div> <slot v-bind:views="views" v-bind:isCurrentView="isCurrentView" v-bind:toggleView="toggleView" v-bind:showView="showView" v-bind:setView="setView" ></slot> </div> </template> <script> export default { props: { initial: { default: () => {} }, syncLocation: { type: Boolean, default: false, }, locationParam: { type: String, default: "view", } }, data() { return { views: this.$props.initial, queryParams: null, keyListener: e => { // Esc if (e.keyCode === 27) { this.hideAllViews(); } } }; }, watch: { routeView() { const queryParams = new URLSearchParams(window.location.search); } }, methods: { setView(viewId, show, hideOthers = false) { if (hideOthers) { Object.keys(this.$data.views).forEach(key => { if (key !== viewId) { this.setView(key, false); } }); } this.$data.views[viewId] = show; if (show && this.$props.syncLocation) { const queryParams = new URLSearchParams(window.location.search); queryParams.set(this.$props.locationParam, viewId); history.pushState(null, null, "?" + queryParams.toString()); } }, setViews(updates) { this.$data.views = Object.assign({}, this.data.views, updates); }, toggleView(viewId) { this.setView(viewId, !this.isCurrentView(viewId), true); }, showView(viewId) { this.setView(viewId, true, true); }, isCurrentView(viewId) { return this.$data.views[viewId]; }, hideAllViews() { Object.keys(this.$data.views).forEach(key => { this.setView(key, false); }); } }, mounted() { window.addEventListener('keydown', this.$data.keyListener); if (this.$props.syncLocation) { const queryParams = new URLSearchParams(window.location.search); const locationView = queryParams.get(this.$props.locationParam); if (Object.keys(this.$data.views).indexOf(locationView) !== -1) { this.showView(locationView); } } }, destroyed() { window.removeEventListener('keydown', this.$data.keyListener); } } </script>