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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
import type { ComponentRenderer } from '../../@types/renderer';
import type { Component as VueComponent } from 'vue';
import { renderToString } from '@vue/server-renderer';
import { defineComponent, createSSRApp, h as createElement } from 'vue';
import { createRenderer } from './renderer';
// This prevents tree-shaking of render.
Function.prototype(renderToString);
/**
* Users might attempt to use :vueAttribute syntax to pass primitive values.
* If so, try to JSON.parse them to get the primitives
*/
function cleanPropsForVue(obj: Record<string, any>) {
let cleaned = {} as any;
for (let [key, value] of Object.entries(obj)) {
if (key.startsWith(':')) {
key = key.slice(1);
if (typeof value === 'string') {
try {
value = JSON.parse(value);
} catch (e) {}
}
}
cleaned[key] = value;
}
return cleaned;
}
const Vue: ComponentRenderer<VueComponent> = {
jsxPragma: createElement,
jsxPragmaName: 'createElement',
renderStatic(Component) {
return async (props, ...children) => {
const App = defineComponent({
components: {
Component,
},
data() {
return { props };
},
template: `<Component v-bind="props">${children.join('\n')}</Component>`,
});
const app = createSSRApp(App);
const html = await renderToString(app);
return html;
};
},
imports: {
vue: ['createApp', 'h: createElement'],
},
render({ Component, root, props, children }) {
const vueProps = cleanPropsForVue(JSON.parse(props));
return `const App = { render: () => createElement(${Component}, ${JSON.stringify(vueProps)}, { default: () => ${children} }) };
createApp(App).mount(${root});`;
},
};
const renderer = createRenderer(Vue);
export const __vue_static = renderer.static;
export const __vue_load = renderer.load;
export const __vue_idle = renderer.idle;
export const __vue_visible = renderer.visible;
|