diff options
author | 2021-04-15 10:55:50 -0500 | |
---|---|---|
committer | 2021-04-15 10:55:50 -0500 | |
commit | 22ca9e0aacf26bf82aa5d0ddd6d1e1d495a1a945 (patch) | |
tree | db56218dd905aca708e39fae6c58d31f99df24dc /src/frontend/render/vue.ts | |
parent | ea33d7b2ab30f6434986bb0d8671e7f681076268 (diff) | |
download | astro-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.ts | 40 |
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});`; }, }; |