-
Notifications
You must be signed in to change notification settings - Fork 257
/
compileSlots.ts
35 lines (32 loc) · 1.36 KB
/
compileSlots.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { compile } from '@vue/compiler-dom'
import * as vue from 'vue'
export function processSlot(source = '', Vue = vue) {
let template = source.trim()
const hasWrappingTemplate = template && template.startsWith('<template')
// allow content without `template` tag, for easier testing
if (!hasWrappingTemplate) {
template = `<template #default="params">${template}</template>`
}
// Vue does not provide an easy way to compile template in "slot" mode
// Since we do not want to rely on compiler internals and specify
// transforms manually we create fake component invocation with the slot we
// need and pick slots param from render function later. Fake component will
// never be instantiated but it requires to be a component so compile
// properly generate invocation. Since we do not want to monkey-patch
// `resolveComponent` function we are just using one of built-in components:
// transition
const { code } = compile(`<transition>${template}</transition>`, {
mode: 'function',
prefixIdentifiers: __USE_PREFIX_IDENTIFIERS__
})
const createRenderFunction = new Function(
'Vue',
__BROWSER__ ? `'use strict';\n${code}` : code
)
const renderFn = createRenderFunction(Vue)
return (ctx = {}) => {
const result = renderFn(ctx)
const slotName = Object.keys(result.children)[0]
return result.children[slotName](ctx)
}
}