代码之家  ›  专栏  ›  技术社区  ›  ThomasReggi

如何将astro组件呈现为HTML字符串?

  •  0
  • ThomasReggi  · 技术社区  · 2 年前

    我希望能够在Astro中有一个动态页面来渲染Astro组件。我已经深入研究了文档和代码,但找不到像下面这样的函数( Astro.render )。理想情况下,我可以将属性传递给它。我正在寻找类似于 react.renderToString

    import Example from './components/Example.astro'
    
    export async function get() {
      return {
        body: Astro.render(Example)
      };
    }
    

    更新:我认为这里的每一个答案都是错的。给定一个astro文件,我想要 node 独立于运行时astro框架,可以获取astro文件并简单地返回 Response (因为我知道astro文件可以返回来自前物质的响应)和 HTML 一串我认为它可以是一个元组 [res, htmlString] 。就像可以转换markdown文件一样,也应该能够处理astro文件。

    0 回复  |  直到 1 年前
        1
  •  5
  •   wassfila    2 年前

    使用Slots将Astro组件渲染为html字符串

    Astro中确实存在对html字符串的渲染,但对于slot,如果您在另一个Wrapper/Serializer中传递组件,则可以很容易地获得其html字符串

    工作示例

    用法

    这是Wrapper组件的主体,它被用于高亮显示,但也与Fragment组件一起渲染

    ---
    const html = await Astro.slots.render('default');
    import { Code } from 'astro/components';
    ---
    <Fragment set:html={html} />
    
    <Code code={html} lang="html" />
    

    用法如下

    例如。 index.astro

    ---
    import Card from '../components/Card.astro';
    import StringWrapper from '../components/StringWrapper.astro';
    ...
    ---
        <StringWrapper>
            <Card title="Test" />
        </StringWrapper>
    
        2
  •  0
  •   HappyDev    2 年前

    Astro组件在服务器上渲染,因此您可以直接引用包含的组件并根据需要传递道具。

    // [title].astro
    
    ---
    import Example from './components/Example.asto'
    ---
    
    <Example message="Hey" />
    
        3
  •  0
  •   solipsist    2 年前

    @HappyDev的建议启发了这一点,虽然不是特别抽象,可能需要一些重构,但它确实有效,并允许您通过构建相应的Astro组件,使用其动态区域和组件在Strapi中构建Astro页面:

    /pages/index.astro

    import SectionType1 from '../components/sections/SectionType1.astro'
    // Import all the components you use to ensure styles and scripts are injected`
    import renderPageContent from '../helpers/renderPageContent'
    const page = await fetch(STRAPIENDPOINT) // <-- Strapi JSON
    const contentParts = page.data.attributes.Sections 
    const pageContentString = await renderPageContent(contentParts)
    ---
    <Layout>
        <div set:html={pageContentString}></div>
    </Layout>   
    

    /helpers/renderPageContent.js

    export default async function (parts) {
    
      const pagePartsContent = [];
      parts.forEach(function (part) {
        let componentRequest = {};
    
        switch (part.__component) {
    
          case "sections.SectionType1":
            componentRequest.path = "SectionType1";
            componentRequest.params = {
              title: part.Title, // Your Strapi fields for this component
              text: part.Text    // watch out for capitalization
            };
            break;
    
    // Add more cases for each component type and its fields
    
        }
        if (Object.keys(componentRequest).length) {
          pagePartsContent.push(componentRequest);
        }
      });
    
      let pagePartsContentString = "";
      
      for (const componentRequest of pagePartsContent) {
        let response = await fetch(
          `${import.meta.env.SITE_URL}/components/${
            componentRequest.path
          }?data=${encodeURIComponent(JSON.stringify(componentRequest.params))}`
        );
    
        let contentString = await response.text();
        // Strip out everything but the component markup so we avoid getting style and script tags in the body
        contentString = contentString.match(/(<section.*?>.*<\/section>)/gims)[0];
        pagePartsContentString += contentString;
      }
    
      return pagePartsContentString;
    }
    

    /组件/节/SectionType1.astro

    ---
    export interface Props {
      title: string;
      text?: string;
    }
    
    const { title, text } = Astro.props as Props;
    ---
    <section>
      <h1>{ title }</h1>
      <p>{ text }</p>
    </section>
    

    /页面/组件/SectionType1.astro

    ---
    import SectionType1 from '../../components/sections/SectionType1.astro';
    import urlParser from '../../helpers/urlparser'
    const { title, text } = urlParser(Astro.url);
    ---
    <SectionType1
      title={title}
      text={text}
      />
    

    /helpers/urlParser.js

    export default function(url) {
      return JSON.parse(Object.fromEntries(new URL(url).searchParams).data)
    }