Skip to content

Instantly share code, notes, and snippets.

@samueleiche
Last active December 6, 2019 20:30
Show Gist options
  • Save samueleiche/c72ea381849df70881aa6f0933e3ea7a to your computer and use it in GitHub Desktop.
Save samueleiche/c72ea381849df70881aa6f0933e3ea7a to your computer and use it in GitHub Desktop.
Portal plugin for Vue.js using Vue observable.
/**
* A Portal Plugin for Vue.js, to render components
* outside of other components, anywhere in the document.
*
* @plugin
* @example
* Vue.use(PortalPlugin);
* {
* computed: {
* portalTarget() {
* return this.$portal.getTarget();
* },
* },
* methods: {
* showFailNotice() {
* this.$portal.setTarget({ template: '<div>Aw, Snap!</div>' });
* },
* },
* template: `
* <div class="portal">
* <component :is="portalTarget"></component>
* </div>
* `,
* }
*/
const PortalPlugin = {
install(Vue) {
const state = Vue.observable({
component: {},
});
const hasKeys = (obj) => {
return obj !== null && typeof obj === 'object' && Object.keys(obj).length;
};
const actions = {
setTarget(component) {
state.component = component;
},
getTarget() {
return hasKeys(state.component) ? state.component : null;
},
};
Vue.prototype.$portal = actions;
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment