summaryrefslogtreecommitdiff
path: root/src/frontend/render/vue.ts
diff options
context:
space:
mode:
authorGravatar Nate Moore <natemoo-re@users.noreply.github.com> 2021-04-15 10:55:50 -0500
committerGravatar GitHub <noreply@github.com> 2021-04-15 10:55:50 -0500
commit22ca9e0aacf26bf82aa5d0ddd6d1e1d495a1a945 (patch)
treedb56218dd905aca708e39fae6c58d31f99df24dc /src/frontend/render/vue.ts
parentea33d7b2ab30f6434986bb0d8671e7f681076268 (diff)
downloadastro-22ca9e0aacf26bf82aa5d0ddd6d1e1d495a1a945.tar.gz
astro-22ca9e0aacf26bf82aa5d0ddd6d1e1d495a1a945.tar.zst
astro-22ca9e0aacf26bf82aa5d0ddd6d1e1d495a1a945.zip
Support children inside of components (#72)
* chore(examples): add kitchen-sink * feat: support children in rendered components * feat: add support for rendering children in Svelte * fix: cleanup p/react fragment children * chore: add @ts-nocheck to svelte files * chore: update lockfiles * fix: types * feat: memoize frontend/renderer/utils * fix: disable eslint for compiled SvelteWrapper * fix: add missing dep Co-authored-by: Nate Moore <nate@skypack.dev>
Diffstat (limited to 'src/frontend/render/vue.ts')
-rw-r--r--src/frontend/render/vue.ts40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/frontend/render/vue.ts b/src/frontend/render/vue.ts
index 628544775..cf2c203be 100644
--- a/src/frontend/render/vue.ts
+++ b/src/frontend/render/vue.ts
@@ -1,20 +1,45 @@
import type { ComponentRenderer } from '../../@types/renderer';
import type { Component as VueComponent } from 'vue';
import { renderToString } from '@vue/server-renderer';
-import { createSSRApp, h as createElement } from 'vue';
+import { defineComponent, createSSRApp, h as createElement } from 'vue';
import { createRenderer } from './renderer';
+/**
+ * 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 = createSSRApp({
+ const App = defineComponent({
components: {
- Component,
+ Component
},
- render() {
- return createElement(Component as any, props);
+ data() {
+ return { props }
},
+ template: `<Component v-bind="props">${children.join('\n')}</Component>`
});
+
+ const app = createSSRApp(App);
const html = await renderToString(app);
return html;
};
@@ -22,8 +47,9 @@ const Vue: ComponentRenderer<VueComponent> = {
imports: {
vue: ['createApp', 'h: createElement'],
},
- render({ Component, root, props }) {
- return `const App = { render() { return createElement(${Component}, ${props} )} };
+ 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});`;
},
};