Skip to content

Instantly share code, notes, and snippets.

@piyushchauhan2011
Forked from treshugart/example.html
Created February 2, 2018 06:16
Show Gist options
  • Save piyushchauhan2011/48f92750d3109975fc553ea7666a6cdd to your computer and use it in GitHub Desktop.
Save piyushchauhan2011/48f92750d3109975fc553ea7666a6cdd to your computer and use it in GitHub Desktop.
Vue renderer for SkateJS. In action: https://www.webpackbin.com/bins/-Ksoy2D-9EEMXzJU6BH_.
<x-vue yell>World</x-vue>
import { props, withProps } from 'skatejs/esnext/with-props';
import { withRender } from 'skatejs/esnext/with-render';
import Vue from 'vue';
// The base Vue component renderer.
//
// Since vue doesn't have an imperative re-render
// (at least I don't think it does) we only allow
// rendering the template once and subsequent prop
// sets don't actually render, but just update the
// instance it has stored from the first render.
const withVue = Base => class extends withRender(withProps(Base || HTMLElement)) {
rendererCallback(renderRoot, renderCallback) {
const { props } = this;
if (this._vue) {
Object.assign(this._vue, props);
} else {
// Vue calls cloneNode() so we can't use the
// shadowRoot directly as "el" because you can't
// clone a shadow root.
const vueRoot = document.createElement('div');
vueRoot.innerHTML = renderCallback();
renderRoot.appendChild(vueRoot);
this._vue = new Vue({
el: vueRoot,
data: props
});
}
}
}
// Simple custom element that uses the Vue renderer
// to show both slotted content via the real-slot
// and props.
class XVue extends withVue() {
static props = {
yell: props.boolean
}
renderCallback() {
return `
Hello,
<strong v-if="yell"><real-slot></real-slot></strong>
<real-slot v-else></real-slot>!
`;
}
}
// Vue eats <slot /> elements because it uses them
// for their internal distirbution algorithm, so we
// must work around it somehow. This just bypasses
// Vue and uses a custom element to render a real
// slot as light DOM. We can't do it as shadow DOM
// because it needs to appear in the context of the
// parent shadow root.
class RealSlot extends HTMLElement {
connectedCallback() {
this.innerHTML = '<slot></slot>';
}
}
customElements.define('real-slot', RealSlot);
customElements.define('x-vue', XVue);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment