Skip to content
On this page

hono-html-jsx

简介

hono-html-jsx 是 Hono 框架提供的 HTML 和 JSX 渲染功能,允许开发者使用 HTML 模板字符串或 JSX 语法来构建响应内容。这些功能使得在 Hono 应用中创建动态 HTML 内容变得简单高效。

安装

bash
npm install hono

HTML 渲染

基本使用

typescript
import { Hono } from 'hono'
import { html } from 'hono/html'

const app = new Hono()

app.get('/', (c) => {
  // 使用模板字符串创建 HTML
  const content = html`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Hono HTML 示例</title>
      </head>
      <body>
        <h1>欢迎使用 Hono!</h1>
        <p>当前时间: ${new Date().toLocaleString()}</p>
      </body>
    </html>
  `

  return c.html(content)
})

app.listen(3000)

高级用法

typescript
import { Hono } from 'hono'
import { html } from 'hono/html'

const app = new Hono()

// 创建可复用的组件
const Layout = (props: { title: string; children: any }) => html`
  <!DOCTYPE html>
  <html>
    <head>
      <title>${props.title}</title>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link href="/static/style.css" rel="stylesheet" />
    </head>
    <body>
      <header>
        <h1>Hono 应用</h1>
        <nav>
          <a href="/">首页</a>
          <a href="/about">关于</a>
        </nav>
      </header>
      <main>${props.children}</main>
      <footer>&copy; ${new Date().getFullYear()} Hono 示例</footer>
    </body>
  </html>
`

const UserCard = (props: { name: string; email: string }) => html`
  <div class="user-card">
    <h3>${props.name}</h3>
    <p>${props.email}</p>
  </div>
`

app.get('/', (c) => {
  const users = [
    { name: '张三', email: 'zhangsan@example.com' },
    { name: '李四', email: 'lisi@example.com' },
  ]

  const content = Layout({
    title: '用户列表',
    children: html`
      <h2>用户列表</h2>
      <div class="user-list">${users.map((user) => UserCard(user))}</div>
    `,
  })

  return c.html(content)
})

app.listen(3000)

JSX 渲染

基本使用

tsx
import { Hono } from 'hono'
import { jsx } from 'hono/jsx'

// 配置 JSX 运行时
/** @jsx jsx */

const app = new Hono()

app.get('/', (c) => {
  return c.jsx(
    <html>
      <head>
        <title>Hono JSX 示例</title>
      </head>
      <body>
        <h1>欢迎使用 Hono JSX!</h1>
        <p>当前时间: {new Date().toLocaleString()}</p>
      </body>
    </html>,
  )
})

app.listen(3000)

高级用法

tsx
import { Hono } from 'hono'
import { jsx } from 'hono/jsx'

/** @jsx jsx */

const app = new Hono()

// 创建可复用的组件
const Layout = (props: { title: string; children: any }) => (
  <html>
    <head>
      <title>{props.title}</title>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link href="/static/style.css" rel="stylesheet" />
    </head>
    <body>
      <header>
        <h1>Hono JSX 应用</h1>
        <nav>
          <a href="/">首页</a>
          <a href="/about">关于</a>
        </nav>
      </header>
      <main>{props.children}</main>
      <footer>&copy; {new Date().getFullYear()} Hono 示例</footer>
    </body>
  </html>
)

const UserCard = (props: { name: string; email: string }) => (
  <div class="user-card">
    <h3>{props.name}</h3>
    <p>{props.email}</p>
  </div>
)

app.get('/', (c) => {
  const users = [
    { name: '张三', email: 'zhangsan@example.com' },
    { name: '李四', email: 'lisi@example.com' },
  ]

  return c.jsx(
    <Layout title="用户列表">
      <h2>用户列表</h2>
      <div class="user-list">
        {users.map((user) => (
          <UserCard name={user.name} email={user.email} />
        ))}
      </div>
    </Layout>,
  )
})

app.listen(3000)

与 TypeScript 集成

tsx
import { Hono } from 'hono'
import { jsx } from 'hono/jsx'

/** @jsx jsx */

type User = {
  id: number
  name: string
  email: string
}

type PageProps = {
  title: string
  children: any
}

type UserCardProps = {
  user: User
  onDelete?: (id: number) => void
}

const app = new Hono()

const Page = ({ title, children }: PageProps) => (
  <html>
    <head>
      <title>{title}</title>
    </head>
    <body>
      <header>
        <h1>{title}</h1>
      </header>
      <main>{children}</main>
    </body>
  </html>
)

const UserCard = ({ user, onDelete }: UserCardProps) => (
  <div class="user-card">
    <h3>{user.name}</h3>
    <p>{user.email}</p>
    {onDelete && <button onClick={`deleteUser(${user.id})`}>删除</button>}
  </div>
)

app.get('/', (c) => {
  const users: User[] = [
    { id: 1, name: '张三', email: 'zhangsan@example.com' },
    { id: 2, name: '李四', email: 'lisi@example.com' },
  ]

  return c.jsx(
    <Page title="用户管理">
      <h2>用户列表</h2>
      <div class="user-list">
        {users.map((user) => (
          <UserCard user={user} onDelete={(id) => console.log(`删除用户 ${id}`)} />
        ))}
      </div>
    </Page>,
  )
})

app.listen(3000)

要保持清醒 永远不抱有意外的幻想 凭空的期待最要命