Skip to content

Instantly share code, notes, and snippets.

@johannes-z
Last active September 8, 2017 13:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johannes-z/62059e7a64c36e0dd70987738cba269a to your computer and use it in GitHub Desktop.
Save johannes-z/62059e7a64c36e0dd70987738cba269a to your computer and use it in GitHub Desktop.
[WIP] Vue directive to generate HTML from a (scoped) slot and values.
import Vue from 'vue'
/**
* Usage:
* <span v-slot:one="{ slots, value: 'component B2' }"></span>
* v-slot:<SLOT_NAME>="{ slots, <VALUE> }"
*
* Pass the slots like this:
* <my-component :slots="$scopedSlots" />
* inside MyComponent define props: ['slots']
*/
const debug = false
function processSlot (el, binding, vnode) {
let name = binding.arg
let obj = binding.value
let slots = obj.slots
let value = obj.value
let createElement = obj.createElement
if (!slots) {
debug && console.error(`Not slots were passed to the directive.`)
return
}
let slot = slots[name]
if (!slot) {
debug && console.warn(`Slot with name "${name}" is not registered.`)
el.innerHTML = value
return
}
let root = slot({ value })
if (!root) return ''
if (!root.map) {
// vnode = root
el.innerHTML = buildElement(root)
return
}
function buildElement (node) {
let element = node.text || ''
if (!node.children) return element
let classes = []
if (node.data) {
for (const [clazz, include] of Object.entries(node.data.class)) {
if (include) classes.push(clazz)
}
classes.push(node.data.staticClass)
}
classes = classes.join('')
node.classes = classes.length > 0 ? `class="${classes}"` : ''
element += `<${node.tag} ${node.classes}>`
node.children.forEach(child => {
element += buildElement(child)
})
element += `</${node.tag}>`
return element
}
var result = root.map(node => buildElement(node))
el.innerHTML = result.join('')
}
Vue.directive('slot', (el, binding, vnode) => processSlot)
Vue.directive('genSlot', (el, binding, vnode) => {
let obj = binding.value
var slot = obj.slot
if (!slot) {
debug && console.error('No slot defined.')
return
}
binding.arg = slot
return processSlot(el, binding, vnode)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment