国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 web前端 js教程 Markdown 中的交互組件

Markdown 中的交互組件

Oct 30, 2024 pm 03:27 PM

最近我實現(xiàn)了一個日歷,結(jié)果非常好,我想記錄該方法并與更廣泛的受眾分享。我真的很想在文章中得到我的工作的實際可測試結(jié)果。

我已經(jīng)調(diào)整我的網(wǎng)站一段時間了,這個想法開始了下一次迭代。最終導(dǎo)致了又一次全面重建,但這個故事并不是關(guān)于我與完美主義的斗爭。這是關(guān)于轉(zhuǎn)動這個:

HTML comes with a lot of ready to use and flexible elements, but date selector
has a handful of limitations and the need to write your own calendar / date
input emerges sooner rather than later. In this tutorial I'll walk you through
implementing a calendar view and show how you can extend its functionality to fit
your booking widget or dashboard filter.

Here's how the final result might look like:

<!--render:custom-calendar-component/CalendarExample.ssi.tsx-->

進入此:

Interactive Components in Markdown

設(shè)置

我的網(wǎng)站在 Deno 上運行,并從最近開始使用 Hono 和 Hono/JSX,但該方法適用于任何基于 JS 的運行時和 JSX。

正如您已經(jīng)注意到的,博客文章是帶有屬性的 Markdown 文件,這些屬性在構(gòu)建時使用 Marked 和 Front Matter 轉(zhuǎn)換為靜態(tài) HTML。

經(jīng)過一番反復(fù)思考,我決定了這個工作流程:

  • 我用markdown寫文章
  • 我在與文章相同的文件夾中創(chuàng)建了一個 JSX 組件
  • 我使用 HTML 注釋在 Markdown 中“導(dǎo)入”組件
  • 它的神奇功效

評論需要某種前綴,例如渲染并且基本上只是該組件的路徑:

<!--render:custom-calendar-component/CalendarExample.ssi.tsx-->

也可以在路徑后添加道具,但對于我的用例來說,不需要它,所以我跳過了這一部分。

渲染 HTML

在瀏覽器上添加任何內(nèi)容之前,我們需要從 JSX 組件渲染 HTML。為此,我們“只”需要使用自定義渲染器覆蓋 HTML 渲染邏輯:

export default class Renderer extends Marked.Renderer {
  constructor(private baseUrl: string, options?: Marked.marked.MarkedOptions) {
    super(options);
  }

  override html(html: string): string {
    const ssiMatch = /<!--render:(.+)-->/.exec(html);
    if (ssiMatch?.length) {
      const filename = ssiMatch[1];
      const ssi = SSIComponents.get(filename);
      if (!ssi) return html;
      const content = render(createElement(ssi.Component, {}));
      return [
        content,
        `<script type="module" src="${ssi.script}"></script>`,
      ].join("");
    }
    return html;
  }
}

邏輯非常簡單:檢查 html 字符串是否匹配 // 然后渲染 JSX。如果您手頭有組件,那就很容易了。

編譯組件

我的博客內(nèi)容是靜態(tài)生成的,所以我很自然地采用了相同的方法:

  • 掃描內(nèi)容文件夾中的 *.ssi.tsx 組件(因此有后綴)
  • 創(chuàng)建一個文件來導(dǎo)入它們并將其添加到地圖中,以便我可以輕松地通過路徑檢索它們

這是我的構(gòu)建腳本的樣子:

const rawContent = await readDir("./content");
const content: Record<string, Article> = {};
const ssi: Array<string> = [];

for (const pathname in rawContent) {
  if (pathname.endsWith(".ssi.tsx")) {
    ssi.push(pathname);
    continue;
  }
}

const scripts = await compileSSI(ssi.map((name) => `./content/${name}`));

const ssiContents = `
import type { FC } from 'hono/jsx';
const SSIComponents = new Map<string,{ Component: FC, script: string }>();
${
  scripts
    ? ssi
        .map(
          (pathname, i) =>
            `SSIComponents.set("${pathname}", { Component: (await import("./${pathname}")).default, script: "${scripts[i]}" })`
        )
        .join("\n")
    : ""
}
export default SSIComponents;
`;

await Deno.writeFile("./content/ssi.ts", new TextEncoder().encode(ssiContents));

不要太執(zhí)著于 Deno 特定功能,它可以輕松地用 Node 或其他任何東西重寫。

神奇之處在于編寫類似于 JavaScript 代碼的文本文件。

這個腳本:

const ssiContents = `
import type { FC } from 'hono/jsx';
const SSIComponents = new Map<string,{ Component: FC, script: string }>();
${
  scripts
    ? ssi
        .map(
          (pathname, i) =>
            `SSIComponents.set("${pathname}", { Component: (await import("./${pathname}")).default, script: "${scripts[i]}" })`
        )
        .join("\n")
    : ""
}
export default SSIComponents;
`;

返回如下字符串:

import type { FC } from 'hono/jsx';
const SSIComponents = new Map<string,{ Component: FC, script: string }>();
SSIComponents.set("custom-calendar-component/CalendarExample.ssi.tsx", { Component: (await import("./custom-calendar-component/CalendarExample.ssi.tsx")).default, script: "/content/custom-calendar-component/CalendarExample.ssi.js" })
export default SSIComponents;

然后可以在渲染器中導(dǎo)入和使用:)

寫代碼的代碼!魔法!并且在此過程中沒有任何人工智能受到傷害:只是你的老式元編程。

最后,最后一個難題是滋潤前端的組件。我使用 esbuild,但我個人打算將其切換到 Vite 或 HMR 附帶的任何其他工具。

盡管如此,它看起來是這樣的:

HTML comes with a lot of ready to use and flexible elements, but date selector
has a handful of limitations and the need to write your own calendar / date
input emerges sooner rather than later. In this tutorial I'll walk you through
implementing a calendar view and show how you can extend its functionality to fit
your booking widget or dashboard filter.

Here's how the final result might look like:

<!--render:custom-calendar-component/CalendarExample.ssi.tsx-->

您可以注意到一個虛擬入口點,其值為零,但會強制 esbuild 在自己的文件夾中創(chuàng)建文件并具有可預(yù)測的路徑。

并且 ssi-tsconfig.json 非常通用:

<!--render:custom-calendar-component/CalendarExample.ssi.tsx-->

在實際的前端水合作用中,我選擇了簡單的方法,并將其添加到我的 .ssi.tsx 文件的底部:

export default class Renderer extends Marked.Renderer {
  constructor(private baseUrl: string, options?: Marked.marked.MarkedOptions) {
    super(options);
  }

  override html(html: string): string {
    const ssiMatch = /<!--render:(.+)-->/.exec(html);
    if (ssiMatch?.length) {
      const filename = ssiMatch[1];
      const ssi = SSIComponents.get(filename);
      if (!ssi) return html;
      const content = render(createElement(ssi.Component, {}));
      return [
        content,
        `<script type="module" src="${ssi.script}"></script>`,
      ].join("");
    }
    return html;
  }
}

我相信讀者會找到一種更優(yōu)雅的方式來做到這一點,但僅此而已!

隨意調(diào)整代碼(下面是存儲庫的鏈接),添加您自己的風(fēng)格并分享您的想法!

Interactive Components in Markdown 瓦萊里婭·VG / valeriavg.dev

以上是Markdown 中的交互組件的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用于不同的應(yīng)用場景。Java用于大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用于網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什么要將標(biāo)簽放在的底部? 為什么要將標(biāo)簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什么是在DOM中冒泡和捕獲的事件? 什么是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動態(tài)內(nèi)容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯誤處理。了解這兩個階段有助于精確控制JavaScript響應(yīng)用戶操作的時機和方式。

JavaScript:探索用于高效編碼的數(shù)據(jù)類型 JavaScript:探索用于高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

See all articles