 与 tinaField 在页面上启用可视化点击编辑)
TinaCMS 如何用 useTina() 与 tinaField 在页面上启用可视化点击编辑【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms如果你的网站用 TinaCMS 管理内容但每次改一个标题、换一张头图都要在后台表单里找字段编辑体验会很差。TinaCMS 的可视化点击编辑contextual editing解决的就是这个问题编辑者在前端页面上直接点击某块内容侧边栏表单会自动聚焦到对应字段输入后预览实时更新。在仓库的示例应用中useTina()与tinaField是实现这一能力的两个核心 API。以 Next.js 15 App Router 的 kitchen-sink 示例examples/next/kitchen-sink/为主线配合 React 18 SPA 示例examples/react/kitchen-sink/可以完整走通从查询内容到启用点击编辑的路径。工作机制数据是怎么和 DOM 关联起来的先看原理后面改代码才知道每行在做什么。完整实现见 packages/tinacms/src/react.tsx 与 packages/tinacms/bridge/src/tina-field.tsuseTina({ query, variables, data })接收 Tina 客户端查询返回的原始三元组通过addMetadata来自tinacms/bridge/metadata给数据打上_content_source元数据再用查询串哈希出一个表单 id通过postMessage把open消息发给父窗口也就是 admin 管理面板的 iframe。tinaField(node, fieldName)读取节点上的_content_source生成格式为queryId---path.to.field的标识字符串数组元素还可传第三个参数index。如果节点上没有元数据它会返回空字符串——所以必须用useTina()处理过的data而不是直接拿查询返回的原始对象。管理面板开启编辑后useTina()会注入 quick-edit 样式并挂一个全局click捕获监听点击任何带data-tina-field属性的元素或其子元素就向父窗口发field:selected消息管理面板据此聚焦侧边栏对应字段。注意点击处理只会使用第一个以data-tina-field开头的属性。管理面板中的编辑通过updateData消息推回页面useTina()更新本地 state预览即时刷新。页面里只要存在带data-tina-field的元素useTina()会向父窗口发quick-edit: true否则发false。examples/AGENTS.md 把这套写法称为规范客户端模式canonical client patternconst { data } useTina({ data, query, variables }); h1>pnpm install cd examples/next/kitchen-sink pnpm devpnpm dev实际执行的是tinacms dev -c next dev --turbopack同时起站点和 TinaCMS。站点运行在http://localhost:3000管理面板在http://localhost:3000/admin。执行步骤给页面启用点击编辑第一步服务端组件负责查询把三元组传下去Next.js App Router 下useTina()只能跑在客户端组件里所以采用「server 查询 client 渲染」的拆分。以博客详情页为例app/blog/[filename]/page.tsx 是服务端组件import client from /tina/__generated__/client; import BlogClientPage from ./client-page; export const revalidate 300; export default async function BlogFile({ params }: Props) { const { filename } await params; const relativePath ${filename}.md; let tinaProps: AwaitedReturnTypetypeof client.queries.blog; try { tinaProps await client.queries.blog({ relativePath }); } catch { notFound(); } return BlogClientPage {...tinaProps} /; }client.queries.blog()的返回本身就包含data、query、variables直接展开传给客户端组件即可。export const revalidate 300是示例里的 5 分钟 ISR 配置与点击编辑本身无关但它是该应用所有列表/详情页的统一配置。第二步客户端组件调用 useTina() 并标注可编辑元素app/blog/[filename]/client-page.tsx 顶部声明use client然后import { useTina, tinaField } from tinacms/dist/react; import { TinaMarkdown } from tinacms/dist/rich-text; export default function BlogClientPage(props: BlogClientProps) { const { data } useTina({ query: props.query, variables: props.variables, data: props.data, }); if (data?.blog) { return ( GradientTitle>pnpm buildpnpm build执行tinacms build next buildtinacms build会把管理面板打包进public/admin//admin路由继续可用。需要离线构建时用pnpm build:localtinacms build --local --skip-cloud-checks -c next build。【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考