[{"data":1,"prerenderedAt":974},["ShallowReactive",2],{"navigation":3,"blogNavigation":232,"page-\u002Fblog\u002F%E6%8A%80%E6%9C%AF%E6%A0%88\u002Festel-docs-recent-updates":418,"\u002Fblog\u002F%E6%8A%80%E6%9C%AF%E6%A0%88\u002Festel-docs-recent-updates-surround":971},[4],{"title":5,"path":6,"stem":7,"children":8,"page":57},"Docs","\u002Fdocs","docs",[9,176,184],{"title":10,"path":11,"stem":12,"children":13,"icon":16},"简单文档","\u002Fdocs\u002F简单文档","docs\u002F1.简单文档\u002F1.index",[14,17,22,58,63,166,171],{"title":15,"path":11,"stem":12,"icon":16},"入门简介","lucide-house",{"title":18,"path":19,"stem":20,"icon":21},"安装与开发","\u002Fdocs\u002F简单文档\u002Finstallation","docs\u002F1.简单文档\u002F2.installation","lucide-play",{"title":23,"path":24,"stem":25,"children":26,"page":57},"开始写作","\u002Fdocs\u002F简单文档\u002Fwriting","docs\u002F1.简单文档\u002F3.writing",[27,32,37,42,47,52],{"title":28,"path":29,"stem":30,"icon":31},"Markdown","\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown","docs\u002F1.简单文档\u002F3.writing\u002F1.markdown","simple-icons:markdown",{"title":33,"path":34,"stem":35,"icon":36},"页面 frontmatter","\u002Fdocs\u002F简单文档\u002Fwriting\u002Fpages","docs\u002F1.简单文档\u002F3.writing\u002F2.pages","lucide:file-text",{"title":38,"path":39,"stem":40,"icon":41},"目录与文件命名","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ffolders","docs\u002F1.简单文档\u002F3.writing\u002F3.folders","lucide:folder",{"title":43,"path":44,"stem":45,"icon":46},"单页面示例","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ffull-page-example","docs\u002F1.简单文档\u002F3.writing\u002F4.full-page-example","lucide:layout-template",{"title":48,"path":49,"stem":50,"icon":51},"内容检查与测试","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest","docs\u002F1.简单文档\u002F3.writing\u002F5.test","lucide:shield-check",{"title":53,"path":54,"stem":55,"icon":56},"在文章中使用组件","\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmdc-content","docs\u002F1.简单文档\u002F3.writing\u002F6.mdc-content","lucide-blocks",false,{"title":59,"path":60,"stem":61,"icon":62},"部署服务","\u002Fdocs\u002F简单文档\u002Fdeployment","docs\u002F1.简单文档\u002F4.deployment","lucide:cloud",{"title":64,"path":65,"stem":66,"children":67,"page":57},"组件特性","\u002Fdocs\u002F简单文档\u002Fcomponents","docs\u002F1.简单文档\u002F5.components",[68,73,77,81,85,89,93,97,101,105,110,114,118,122,126,131,136,141,146,150,154,158,162],{"title":69,"path":70,"stem":71,"icon":72},"常用组件","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fapi","docs\u002F1.简单文档\u002F5.components\u002F1.API","lucide-component",{"title":74,"path":75,"stem":76},"Alert","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert","docs\u002F1.简单文档\u002F5.components\u002Falert",{"title":78,"path":79,"stem":80},"Badge","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge","docs\u002F1.简单文档\u002F5.components\u002Fbadge",{"title":82,"path":83,"stem":84},"Button Link","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbutton-link","docs\u002F1.简单文档\u002F5.components\u002Fbutton-link",{"title":86,"path":87,"stem":88},"Callout","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcallout","docs\u002F1.简单文档\u002F5.components\u002Fcallout",{"title":90,"path":91,"stem":92},"Card","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard","docs\u002F1.简单文档\u002F5.components\u002Fcard",{"title":94,"path":95,"stem":96},"Card Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard-group","docs\u002F1.简单文档\u002F5.components\u002Fcard-group",{"title":98,"path":99,"stem":100},"Code Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-group","docs\u002F1.简单文档\u002F5.components\u002Fcode-group",{"title":102,"path":103,"stem":104},"Code Tree","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-tree","docs\u002F1.简单文档\u002F5.components\u002Fcode-tree",{"title":106,"path":107,"stem":108,"icon":109},"博客与文档内容块","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcontent-blocks","docs\u002F1.简单文档\u002F5.components\u002Fcontent-blocks","lucide-panels-top-left",{"title":111,"path":112,"stem":113},"Field","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield","docs\u002F1.简单文档\u002F5.components\u002Ffield",{"title":115,"path":116,"stem":117},"Field Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield-group","docs\u002F1.简单文档\u002F5.components\u002Ffield-group",{"title":119,"path":120,"stem":121},"File Tree","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree","docs\u002F1.简单文档\u002F5.components\u002Ffile-tree",{"title":123,"path":124,"stem":125},"Icon","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ficon","docs\u002F1.简单文档\u002F5.components\u002Ficon",{"title":127,"path":128,"stem":129,"icon":130},"数据、API 与阅读交互组件","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Finteractive-blocks","docs\u002F1.简单文档\u002F5.components\u002Finteractive-blocks","lucide-table-properties",{"title":132,"path":133,"stem":134,"icon":135},"进阶组件交互演示","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Finteractive-showcase","docs\u002F1.简单文档\u002F5.components\u002Finteractive-showcase","lucide-sliders-horizontal",{"title":137,"path":138,"stem":139,"icon":140},"MDC 语法与组件注册","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fmdc-guide","docs\u002F1.简单文档\u002F5.components\u002Fmdc-guide","lucide-file-code",{"title":142,"path":143,"stem":144,"icon":145},"MDC 组件交互演示","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fmdc-showcase","docs\u002F1.简单文档\u002F5.components\u002Fmdc-showcase","lucide-mouse-pointer-click",{"title":147,"path":148,"stem":149},"Playground","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground","docs\u002F1.简单文档\u002F5.components\u002Fplayground",{"title":151,"path":152,"stem":153},"Read More","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fread-more","docs\u002F1.简单文档\u002F5.components\u002Fread-more",{"title":155,"path":156,"stem":157},"Stack","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fstack","docs\u002F1.简单文档\u002F5.components\u002Fstack",{"title":159,"path":160,"stem":161},"Steps","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fsteps","docs\u002F1.简单文档\u002F5.components\u002Fsteps",{"title":163,"path":164,"stem":165},"Tabs","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs","docs\u002F1.简单文档\u002F5.components\u002Ftabs",{"title":167,"path":168,"stem":169,"icon":170},"功能与路线图","\u002Fdocs\u002F简单文档\u002F功能与路线图","docs\u002F1.简单文档\u002F6.功能与路线图","lucide:map",{"title":172,"path":173,"stem":174,"icon":175},"Nuxt Studio 现状与运维说明","\u002Fdocs\u002F简单文档\u002Fnuxt-studio-upgrade-plan","docs\u002F1.简单文档\u002F7.nuxt-studio-upgrade-plan","simple-icons:nuxtdotjs",{"title":177,"path":178,"stem":179,"children":180,"icon":183},"无人自助系统","\u002Fdocs\u002F无人自助系统","docs\u002F2.无人自助系统\u002F1.index",[181],{"title":182,"path":178,"stem":179,"icon":183},"介绍","simple-icons:opencollective",{"title":185,"path":186,"stem":187,"children":188,"icon":191},"SwitchOps 交换机巡检","\u002Fdocs\u002Fswitchops交换机巡检","docs\u002F3.SwitchOps交换机巡检\u002F1.index",[189,192,197,202,207,212,217,222,227],{"title":190,"path":186,"stem":187,"icon":191},"产品简介","lucide:house",{"title":193,"path":194,"stem":195,"icon":196},"快速开始","\u002Fdocs\u002Fswitchops交换机巡检\u002Fquick-start","docs\u002F3.SwitchOps交换机巡检\u002F2.quick-start","lucide:rocket",{"title":198,"path":199,"stem":200,"icon":201},"设备清单配置","\u002Fdocs\u002Fswitchops交换机巡检\u002Fdevice-config","docs\u002F3.SwitchOps交换机巡检\u002F3.device-config","lucide:list-tree",{"title":203,"path":204,"stem":205,"icon":206},"图形界面使用","\u002Fdocs\u002Fswitchops交换机巡检\u002Fgui-guide","docs\u002F3.SwitchOps交换机巡检\u002F4.gui-guide","lucide:monitor",{"title":208,"path":209,"stem":210,"icon":211},"命令行使用","\u002Fdocs\u002Fswitchops交换机巡检\u002Fcli-guide","docs\u002F3.SwitchOps交换机巡检\u002F5.cli-guide","lucide:square-terminal",{"title":213,"path":214,"stem":215,"icon":216},"报告与历史数据","\u002Fdocs\u002Fswitchops交换机巡检\u002Freports-history","docs\u002F3.SwitchOps交换机巡检\u002F6.reports-history","lucide:file-chart-column",{"title":218,"path":219,"stem":220,"icon":221},"高级配置","\u002Fdocs\u002Fswitchops交换机巡检\u002Fadvanced-config","docs\u002F3.SwitchOps交换机巡检\u002F7.advanced-config","lucide:settings",{"title":223,"path":224,"stem":225,"icon":226},"Windows 打包部署","\u002Fdocs\u002Fswitchops交换机巡检\u002Fwindows-deployment","docs\u002F3.SwitchOps交换机巡检\u002F8.windows-deployment","lucide:package",{"title":228,"path":229,"stem":230,"icon":231},"故障排查与安全","\u002Fdocs\u002Fswitchops交换机巡检\u002Ftroubleshooting-security","docs\u002F3.SwitchOps交换机巡检\u002F9.troubleshooting-security","lucide:shield-alert",[233],{"title":234,"path":235,"stem":236,"children":237,"page":57},"Blog","\u002Fblog","blog",[238,401,410],{"title":239,"path":240,"stem":241,"children":242,"page":57},"技术栈","\u002Fblog\u002F技术栈","blog\u002F1.技术栈",[243,248,253,258,262,267,271,276,280,284,289,294,299,303,307,311,315,319,324,328,333,338,343,347,352,357,362,367,372,376,381,386,391,396],{"title":244,"path":245,"stem":246,"icon":247},"最近给文档站补了些什么","\u002Fblog\u002F技术栈\u002Festel-docs-recent-updates","blog\u002F1.技术栈\u002F968.estel-docs-recent-updates","lucide:blocks",{"title":249,"path":250,"stem":251,"icon":252},"国产化终端能上办公网，却登录不了 OA：一次网络准入故障排查","\u002Fblog\u002F技术栈\u002F国产化终端办公oa网络准入故障排查","blog\u002F1.技术栈\u002F969.国产化终端办公OA网络准入故障排查","lucide:network",{"title":254,"path":255,"stem":256,"icon":257},"准备新的插件","\u002Fblog\u002F技术栈\u002F新的插件","blog\u002F1.技术栈\u002F970.新的插件","simple-icons:debian",{"title":259,"path":260,"stem":261,"icon":257},"防于未然，先固不破 — Debian 12 快速加固实战","\u002Fblog\u002F技术栈\u002F服务器加固实战","blog\u002F1.技术栈\u002F971.服务器加固实战",{"title":263,"path":264,"stem":265,"icon":266},"nmap高级应用技巧-实战","\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-实战","blog\u002F1.技术栈\u002F972.nmap高级应用技巧-实战","simple-icons:openstreetmap",{"title":268,"path":269,"stem":270,"icon":266},"nmap高级应用技巧-NSE","\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse","blog\u002F1.技术栈\u002F973.nmap高级应用技巧-NSE",{"title":272,"path":273,"stem":274,"icon":275},"部分vue组件语法预览","\u002Fblog\u002F技术栈\u002F部分组件语法展示","blog\u002F1.技术栈\u002F974.部分组件语法展示","simple-icons:vuedotjs",{"title":277,"path":278,"stem":279,"icon":175},"新的文档渲染样式","\u002Fblog\u002F技术栈\u002F新的文档渲染样式","blog\u002F1.技术栈\u002F975.新的文档渲染样式",{"title":281,"path":282,"stem":283,"icon":175},"Nuxt 微信分享接口","\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口","blog\u002F1.技术栈\u002F976.Nuxt 微信分享接口",{"title":285,"path":286,"stem":287,"icon":288},"AI复合应用 合同审查","\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查","blog\u002F1.技术栈\u002F978.AI复合应用 合同审查","simple-icons:openai",{"title":290,"path":291,"stem":292,"icon":293},"Kali 安装 GVM","\u002Fblog\u002F技术栈\u002Fkali-安装-gvm","blog\u002F1.技术栈\u002F979.Kali 安装 GVM","simple-icons:kalilinux",{"title":295,"path":296,"stem":297,"icon":298},"GPT-5","\u002Fblog\u002F技术栈\u002Fgpt5","blog\u002F1.技术栈\u002F980.GPT5","simple-icons:powershell",{"title":300,"path":301,"stem":302,"icon":288},"使用 AI 守护内网安全","\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全","blog\u002F1.技术栈\u002F981.使用 AI 守护内网安全",{"title":304,"path":305,"stem":306,"icon":266},"系统安全扫描工具命令集合","\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合","blog\u002F1.技术栈\u002F982.系统安全扫描工具命令集合",{"title":308,"path":309,"stem":310},"用 MDC 组织技术文章","\u002Fblog\u002F技术栈\u002Fmdc-article-example","blog\u002F1.技术栈\u002F983.mdc-article-example",{"title":312,"path":313,"stem":314,"icon":293},"系统安全综合评估报告","\u002Fblog\u002F技术栈\u002F系统安全综合评估报告","blog\u002F1.技术栈\u002F983.系统安全综合评估报告",{"title":316,"path":317,"stem":318},"用交互组件写一份技术说明","\u002Fblog\u002F技术栈\u002Fmdc-interactive-example","blog\u002F1.技术栈\u002F984.mdc-interactive-example",{"title":320,"path":321,"stem":322,"icon":323},"树莓派安装 Kali Linux","\u002Fblog\u002F技术栈\u002F树莓派安装-kali-linux","blog\u002F1.技术栈\u002F984.树莓派安装 Kali Linux","simple-icons:raspberrypi",{"title":325,"path":326,"stem":327,"icon":175},"Nuxt UI Pro","\u002Fblog\u002F技术栈\u002Fnuxt-ui-pro","blog\u002F1.技术栈\u002F985.Nuxt UI Pro",{"title":329,"path":330,"stem":331,"icon":332},"Supabase 阿里云短信","\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信","blog\u002F1.技术栈\u002F986.Supabase 阿里云短信","simple-icons:alibabacloud",{"title":334,"path":335,"stem":336,"icon":337},"Coolify","\u002Fblog\u002F技术栈\u002Fcoolify","blog\u002F1.技术栈\u002F987.Coolify","simple-icons:chai",{"title":339,"path":340,"stem":341,"icon":342},"Python 代码规范","\u002Fblog\u002F技术栈\u002Fpython-代码规范","blog\u002F1.技术栈\u002F988.Python 代码规范","simple-icons:python",{"title":344,"path":345,"stem":346,"icon":175},"Nuxt3 代码规范","\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范","blog\u002F1.技术栈\u002F989.Nuxt3 代码规范",{"title":348,"path":349,"stem":350,"icon":351},"Linux 系统 Swap 分区配置指南","\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南","blog\u002F1.技术栈\u002F990.Linux 系统 Swap 分区配置指南","simple-icons:linux",{"title":353,"path":354,"stem":355,"icon":356},"从Supabase迁移到Appwrite","\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite","blog\u002F1.技术栈\u002F991.从Supabase迁移到Appwrite","simple-icons:supabase",{"title":358,"path":359,"stem":360,"icon":361},"AppWrite 项目资源占用情况","\u002Fblog\u002F技术栈\u002Fappwrite-项目资源占用情况","blog\u002F1.技术栈\u002F992.AppWrite 项目资源占用情况","simple-icons:appwrite",{"title":363,"path":364,"stem":365,"icon":366},"Docker 里配置hosts","\u002Fblog\u002F技术栈\u002Fdocker-里配置hosts","blog\u002F1.技术栈\u002F993.Docker 里配置hosts","simple-icons:docker",{"title":368,"path":369,"stem":370,"icon":371},"MySQL 中如何忽略表名的大小写","\u002Fblog\u002F技术栈\u002Fmysql-中如何忽略表名的大小写","blog\u002F1.技术栈\u002F994.MySQL 中如何忽略表名的大小写","simple-icons:mysql",{"title":373,"path":374,"stem":375,"icon":257},"Debian 12 安装nodejs","\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs","blog\u002F1.技术栈\u002F995.Debian 12 安装nodejs",{"title":377,"path":378,"stem":379,"icon":380},"Dify + Supabase：打造带数据库的AI问答机器人","\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人","blog\u002F1.技术栈\u002F996.Dify + Supabase：打造带数据库的AI问答机器人","simple-icons:reactbootstrap",{"title":382,"path":383,"stem":384,"icon":385},"安装 VS Code到浏览器 -- Code Server","\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy","blog\u002F1.技术栈\u002F996.安装 VS Code到浏览器 -- Code Server copy","simple-icons:visualstudiocode",{"title":387,"path":388,"stem":389,"icon":390},"Debian 12 云服务器初始安全设置与优化指南","\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南","blog\u002F1.技术栈\u002F997.Debian 12 云服务器初始安全设置与优化指南","lucide-server",{"title":392,"path":393,"stem":394,"icon":395},"Iperf3 万兆网络打流测试指南","\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南","blog\u002F1.技术栈\u002F998.Iperf3 万兆网络打流测试指南","lucide-network",{"title":397,"path":398,"stem":399,"icon":400},"GROK3 and Deepseek","\u002Fblog\u002F技术栈\u002Fgrok3-and-deepseek","blog\u002F1.技术栈\u002F999.GROK3-and-Deepseek","lucide-brain",{"title":402,"path":403,"stem":404,"children":405,"page":57},"AI","\u002Fblog\u002Fai","blog\u002F2.AI",[406],{"title":407,"path":408,"stem":409,"icon":337},"AI最佳实践","\u002Fblog\u002Fai\u002Fai","blog\u002F2.AI\u002F01.AI",{"title":411,"path":412,"stem":413,"children":414,"page":57},"生活","\u002Fblog\u002F生活","blog\u002F3.生活",[415],{"title":411,"path":416,"stem":417,"icon":337},"\u002Fblog\u002F生活\u002F生活","blog\u002F3.生活\u002F01.生活",{"id":419,"title":244,"body":420,"category":957,"date":958,"description":959,"draft":57,"extension":960,"icon":957,"img":961,"links":957,"meta":962,"navigation":963,"path":245,"rawbody":964,"readingMinutes":574,"seo":965,"stem":246,"tags":966,"updated":957,"__hash__":970},"blog\u002Fblog\u002F1.技术栈\u002F968.estel-docs-recent-updates.md",{"type":421,"value":422,"toc":945},"minimark",[423,427,430,434,437,440,448,452,455,458,461,464,468,471,480,483,486,490,497,500,507,510,514,524,686,689,693,699,847,857,860,867,874,881,884,887,892,895,901,908,911,914,917,938,941],[424,425,426],"p",{},"这两天更新了文档站的依赖，也把首页入口、内容渲染和发布检查重新过了一遍。改动比较散，单看提交记录不太好找，放在这里记一下。",[424,428,429],{},"其中一个问题很直观：从首页点“文档”，再选巡检工具，明明内容文件在，却进不去。这个入口已经修好。后面又补了一批 MDC 组件，文档和博客都能直接用，下面顺带放几个例子。",[431,432,433],"h2",{"id":433},"先把点不开的文档修好",[424,435,436],{},"问题出在路径解析。浏览器中的 URL 和内容库记录的路径没有统一处理，中文编码、大小写和末尾斜杠混在一起，查询时就可能找不到对应页面。",[424,438,439],{},"现在先规范路径，再查询内容。巡检工具的首页入口、文档内部跳转、直接刷新和原始 Markdown 页面一起检查过，避免只修好其中一个入口。",[424,441,442,443,447],{},"顺手也核对了草稿的发布行为。生产构建会排除标记为 ",[444,445,446],"code",{},"draft: true"," 的内容，导航、搜索和 Feed 等公开入口跟着使用公开内容。写到一半的稿子，就先留在草稿里。",[431,449,451],{"id":450},"依赖更新了但没有硬追版本号","依赖更新了，但没有硬追版本号",[424,453,454],{},"这次把 Nuxt、Content、UI 和测试工具等依赖更新了一轮。当前主框架是 Nuxt 4.5.2、Nuxt Content 3.16.1、Nuxt UI 4.11.3，包管理器使用 pnpm 12.8.1。",[424,456,457],{},"TypeScript 暂时留在 6.0.3。尝试升级到 7 时，ESLint 和 Vue 类型检查遇到了兼容问题，先退回能通过检查的版本。这件事留了工单，等工具链跟上再处理。",[424,459,460],{},"生产检查也补了些过去容易漏掉的地方：代码检查、内容链接、类型、单元测试、构建后的页面测试，以及 Go 微信签名服务的检查。Docker 增加健康检查，CI 里还会实际启动容器，确认内容查询和图片处理能跑。",[424,462,463],{},"这里记的是仓库里的改动，线上效果还要等发布后确认。",[431,465,467],{"id":466},"页面看起来正常也可能藏着渲染问题","页面看起来正常，也可能藏着渲染问题",[424,469,470],{},"这次还修了图片、示例标题和公式样式的几个小问题。有些 HTML 结构浏览器会自行纠正，肉眼看不出来，但 Vue 接管页面时就可能发现前后结构对不上。",[424,472,473,474,479],{},"这里的 ",[475,476],"glossary-term",{"definition":477,"term":478},"浏览器中的 Vue 接管服务端生成的 HTML，为页面连接事件和响应式状态。","Hydration","，就是服务端页面交到浏览器后的那一步。",[424,481,482],{},"图片容器和标题示例的结构调整后，服务端与浏览器保持一致；MathJax 生成的样式也单独处理了。代码主题、行号和图注设置则接上了实际渲染，刷新后会恢复已保存的选项。",[424,484,485],{},"另外，Studio 的生产入口现在默认关闭。需要在线编辑时再按部署说明启用，把 OAuth 和会话密钥放在运行环境里。",[431,487,489],{"id":488},"新组件先从能用上的几个说起","新组件，先从能用上的几个说起",[424,491,492,493,496],{},"以前写设备清单、参数说明，基本都靠普通表格。内容少的时候够用，行数一多，找东西就得来回翻。现在有了 ",[444,494,495],{},"DataTable","，表格里能搜索、排序和分页。",[424,498,499],{},"下面把这次改动列成一张表。试着搜“组件”，或者点“类别”排序；清空搜索后可以翻页。",[501,502],"data-table",{":columns":503,":pageSize":504,":rows":505,"title":506},"[{\"key\":\"area\",\"label\":\"类别\"},{\"key\":\"change\",\"label\":\"改动\"},{\"key\":\"detail\",\"label\":\"现在的行为\"}]","4","[{\"area\":\"文档入口\",\"change\":\"统一路径解析\",\"detail\":\"首页巡检文档入口、刷新和原始 Markdown 查询使用相同规则\"},{\"area\":\"内容发布\",\"change\":\"排除生产草稿\",\"detail\":\"草稿不进入公开内容集合\"},{\"area\":\"页面渲染\",\"change\":\"调整图片、标题和公式样式\",\"detail\":\"修复相关服务端与客户端渲染不一致的问题\"},{\"area\":\"阅读设置\",\"change\":\"联动代码主题、行号和图注\",\"detail\":\"设置影响页面渲染，刷新后恢复选项\"},{\"area\":\"内容组件\",\"change\":\"增加文章排版组件\",\"detail\":\"摘要、折叠说明、时间线、清单和图库可直接写入 Markdown\"},{\"area\":\"内容组件\",\"change\":\"增加数据与阅读交互组件\",\"detail\":\"参数表、数据表、图片对比、术语、自测和下载入口\"},{\"area\":\"生产部署\",\"change\":\"收紧 Studio 配置并增加容器检查\",\"detail\":\"编辑入口按需启用，镜像通过检查后再发布\"}]","本次改动速查",[424,508,509],{},"数据还是写在 Markdown 里，组件只负责页面内的查找和展示。没有给这个表另外接一个接口。",[511,512,513],"h3",{"id":513},"接口说明不用拆成几张表",[424,515,516,519,520,523],{},[444,517,518],{},"ApiEndpoint"," 和 ",[444,521,522],{},"ParameterTable"," 可以放在一起。拿仓库已有的微信签名接口举个例子，方法、路径、参数和请求响应都放在一个块里：",[525,526,531,534,539,578],"api-endpoint",{":status":527,"method":528,"path":529,"title":530},"200","POST","\u002Fapi\u002Fwechat\u002Fjs-sign","获取微信 JS-SDK 签名",[424,532,533],{},"这是独立 Go 服务提供的接口，需部署服务并配置允许的来源和签名域名。这里只展示格式，响应中的值是占位示例，不能用于微信初始化。",[535,536],"parameter-table",{":parameters":537,"title":538},"[{\"name\":\"url\",\"type\":\"string\",\"location\":\"body\",\"required\":true,\"description\":\"需要签名的页面完整地址；域名需在服务端白名单中，hash 会被移除\"}]","请求参数",[540,541,543],"template",{"v-slot:request":542},"",[544,545,549],"pre",{"className":546,"code":547,"language":548,"meta":542,"style":542},"language-http shiki shiki-themes github-light github-light github-dark vitesse-light vitesse-dark catppuccin-latte catppuccin-mocha one-light one-dark-pro material-theme-lighter material-theme-palenight min-light min-dark","POST \u002Fapi\u002Fwechat\u002Fjs-sign HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{ \"url\": \"https:\u002F\u002Flijue.net\u002Fdocs\" }\n","http",[444,550,551,559,565,572],{"__ignoreMap":542},[552,553,556],"span",{"class":554,"line":555},"line",1,[552,557,558],{},"POST \u002Fapi\u002Fwechat\u002Fjs-sign HTTP\u002F1.1\n",[552,560,562],{"class":554,"line":561},2,[552,563,564],{},"Content-Type: application\u002Fjson\n",[552,566,568],{"class":554,"line":567},3,[552,569,571],{"emptyLinePlaceholder":570},true,"\n",[552,573,575],{"class":554,"line":574},4,[552,576,577],{},"{ \"url\": \"https:\u002F\u002Flijue.net\u002Fdocs\" }\n",[540,579,580],{"v-slot:response":542},[544,581,585],{"className":582,"code":583,"language":584,"meta":542,"style":542},"language-json shiki shiki-themes github-light github-light github-dark vitesse-light vitesse-dark catppuccin-latte catppuccin-mocha one-light one-dark-pro material-theme-lighter material-theme-palenight min-light min-dark","{\n  \"appId\": \"wx-example\",\n  \"timestamp\": 1791043200,\n  \"nonceStr\": \"example-nonce\",\n  \"signature\": \"example-signature\"\n}\n","json",[444,586,587,593,623,640,660,680],{"__ignoreMap":542},[552,588,589],{"class":554,"line":555},[552,590,592],{"class":591},"sIQTy","{\n",[552,594,595,599,603,606,610,614,618,620],{"class":554,"line":561},[552,596,598],{"class":597},"sOgDI","  \"",[552,600,602],{"class":601},"sSdLo","appId",[552,604,605],{"class":597},"\"",[552,607,609],{"class":608},"sRS6S",":",[552,611,613],{"class":612},"sLXf0"," \"",[552,615,617],{"class":616},"sCtJb","wx-example",[552,619,605],{"class":612},[552,621,622],{"class":608},",\n",[552,624,625,627,630,632,634,638],{"class":554,"line":567},[552,626,598],{"class":597},[552,628,629],{"class":601},"timestamp",[552,631,605],{"class":597},[552,633,609],{"class":608},[552,635,637],{"class":636},"s_Zq6"," 1791043200",[552,639,622],{"class":608},[552,641,642,644,647,649,651,653,656,658],{"class":554,"line":574},[552,643,598],{"class":597},[552,645,646],{"class":601},"nonceStr",[552,648,605],{"class":597},[552,650,609],{"class":608},[552,652,613],{"class":612},[552,654,655],{"class":616},"example-nonce",[552,657,605],{"class":612},[552,659,622],{"class":608},[552,661,663,665,668,670,672,674,677],{"class":554,"line":662},5,[552,664,598],{"class":597},[552,666,667],{"class":601},"signature",[552,669,605],{"class":597},[552,671,609],{"class":608},[552,673,613],{"class":612},[552,675,676],{"class":616},"example-signature",[552,678,679],{"class":612},"\"\n",[552,681,683],{"class":554,"line":682},6,[552,684,685],{"class":591},"}\n",[424,687,688],{},"这个组件不会请求上面的接口。它解决的是“说明怎么排”，真要测试接口，还是用自己的客户端或命令行。",[511,690,692],{"id":691},"长说明可以收起来源码也能放进去","长说明可以收起来，源码也能放进去",[424,694,695,698],{},[444,696,697],{},"ExpandBox"," 是一个折叠块。参数不多时把代码放进去，正文就不用同时铺开效果和源码。点开下面这段，可以复制一个最小的接口说明：",[700,701,703],"expand-box",{"title":702},"查看 ApiEndpoint 的 MDC 写法",[544,704,708],{"className":705,"code":706,"language":707,"meta":542,"style":542},"language-mdc shiki shiki-themes github-light github-light github-dark vitesse-light vitesse-dark catppuccin-latte catppuccin-mocha one-light one-dark-pro material-theme-lighter material-theme-palenight min-light min-dark",":::api-endpoint{title=\"查询示例报告\" method=\"GET\" path=\"\u002Fapi\u002Freports\u002F{id}\" :status=\"200\"}\n这是一个虚构接口，仅用于说明布局。\n\n#request\n```http\nGET \u002Fapi\u002Freports\u002Fdemo HTTP\u002F1.1\n```\n\n#response\n```json\n{ \"id\": \"demo\", \"status\": \"ready\" }\n```\n:::\n","mdc",[444,709,710,774,780,784,789,799,805,811,816,822,830,836,841],{"__ignoreMap":542},[552,711,712,716,719,722,726,730,732,735,737,740,742,744,747,749,752,754,756,759,761,764,766,768,770,772],{"class":554,"line":555},[552,713,715],{"class":714},"s4Bi8",":::",[552,717,525],{"class":718},"spV5I",[552,720,721],{"class":714},"{",[552,723,725],{"class":724},"shR_7","title",[552,727,729],{"class":728},"stNAY","=",[552,731,605],{"class":612},[552,733,734],{"class":616},"查询示例报告",[552,736,605],{"class":612},[552,738,739],{"class":724}," method",[552,741,729],{"class":728},[552,743,605],{"class":612},[552,745,746],{"class":616},"GET",[552,748,605],{"class":612},[552,750,751],{"class":724}," path",[552,753,729],{"class":728},[552,755,605],{"class":612},[552,757,758],{"class":616},"\u002Fapi\u002Freports\u002F{id}",[552,760,605],{"class":612},[552,762,763],{"class":724}," :status",[552,765,729],{"class":728},[552,767,605],{"class":612},[552,769,527],{"class":616},[552,771,605],{"class":612},[552,773,685],{"class":714},[552,775,776],{"class":554,"line":561},[552,777,779],{"class":778},"sw9Yk","这是一个虚构接口，仅用于说明布局。\n",[552,781,782],{"class":554,"line":567},[552,783,571],{"emptyLinePlaceholder":570},[552,785,786],{"class":554,"line":574},[552,787,788],{"class":724},"#request\n",[552,790,791,795],{"class":554,"line":662},[552,792,794],{"class":793},"sO_xl","```",[552,796,798],{"class":797},"ssTbb","http\n",[552,800,801],{"class":554,"line":682},[552,802,804],{"class":803},"sMLmi","GET \u002Fapi\u002Freports\u002Fdemo HTTP\u002F1.1\n",[552,806,808],{"class":554,"line":807},7,[552,809,810],{"class":793},"```\n",[552,812,814],{"class":554,"line":813},8,[552,815,571],{"emptyLinePlaceholder":570},[552,817,819],{"class":554,"line":818},9,[552,820,821],{"class":724},"#response\n",[552,823,825,827],{"class":554,"line":824},10,[552,826,794],{"class":793},[552,828,829],{"class":797},"json\n",[552,831,833],{"class":554,"line":832},11,[552,834,835],{"class":803},"{ \"id\": \"demo\", \"status\": \"ready\" }\n",[552,837,839],{"class":554,"line":838},12,[552,840,810],{"class":793},[552,842,844],{"class":554,"line":843},13,[552,845,846],{"class":714},":::\n",[424,848,849,850,519,853,856],{},"组件名用短横线写，嵌套时外层多一个冒号。上面的 ",[444,851,852],{},"#request",[444,854,855],{},"#response"," 是插槽名，不是文章标题。",[511,858,859],{"id":859},"示例文件有个明确的下载位置",[424,861,862,863,866],{},"文章里附配置片段，读者有时想直接拿文件改。",[444,864,865],{},"DownloadCard"," 可以把文件名和用途放在链接旁边：",[868,869],"download-card",{"description":870,"filename":871,"href":872,"title":873},"两条文档示例地址，不含账号密码；字段需按实际工具格式调整。","devices.example.json","\u002Fexamples\u002Fdevices.example.json","设备清单示例 JSON",[424,875,876,877,880],{},"这个文件用来演示下载，不是巡检工具的正式配置模板。文件放在 ",[444,878,879],{},"public\u002F"," 中，卡片指向它已有的地址。",[511,882,883],{"id":883},"操作指南可以加一份核对清单",[424,885,886],{},"清单能勾选，也能看到完成了几项。写部署说明、故障排查记录时，放在最后比较合适。",[888,889],"task-checklist",{":items":890,"title":891},"[{\"label\":\"打开页面，确认效果和源码一致\"},{\"label\":\"用手机宽度试一下表格和参数说明\"},{\"label\":\"点开下载，确认拿到的是示例文件\"}]","写完一篇带组件的文章后",[424,893,894],{},"勾选只保留在当前页面，刷新就恢复初始状态。如果需要长期记录执行结果，那是另一项功能。",[424,896,897,900],{},[444,898,899],{},"ContentQuiz"," 也采用相同的页面内交互方式，适合教程里的小题。比如检查一下刚才的插槽写法：",[902,903],"content-quiz",{":answer":904,":choices":905,"explanation":906,"question":907},"1","[\"request\",\"response\",\"takeaway\"]","response 放响应示例，request 放请求示例；takeaway 是 ArticleSummary 的插槽。","ApiEndpoint 中的响应示例应该放在哪个插槽？",[424,909,910],{},"答案写在公开内容里，组件只给阅读反馈，不记录成绩。",[431,912,913],{"id":913},"说明也一起补上了",[424,915,916],{},"这轮还加了摘要、链接卡片、引用、数字概览、时间线、图库和图片对比。连同原来的卡片、标签页、文件树等，目前有 27 个公共自定义组件。普通段落能说明白的地方，仍然直接写 Markdown，不需要每一节都套卡片。",[424,918,919,920,924,925,928,929,519,933,937],{},"“简单文档”里补了一篇 ",[921,922,53],"a",{"href":923},"\u002Fdocs\u002F%E7%AE%80%E5%8D%95%E6%96%87%E6%A1%A3\u002Fwriting\u002Fmdc-content","，把效果和可复制的代码放在一起。查参数可以看 ",[921,926,69],{"href":927},"\u002Fdocs\u002F%E7%AE%80%E5%8D%95%E6%96%87%E6%A1%A3\u002Fcomponents\u002Fapi","，想试图库、图片对比等交互，就去 ",[921,930,932],{"href":931},"\u002Fdocs\u002F%E7%AE%80%E5%8D%95%E6%96%87%E6%A1%A3\u002Fcomponents\u002Fmdc-showcase","内容组件演示",[921,934,936],{"href":935},"\u002Fdocs\u002F%E7%AE%80%E5%8D%95%E6%96%87%E6%A1%A3\u002Fcomponents\u002Finteractive-showcase","进阶组件演示","。",[424,939,940],{},"后面写巡检工具说明、排障记录和配置指南时，就可以直接用这些现成的块了。",[942,943,944],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .code-theme-vitesse-light .shiki span {color: var(--shiki-code-theme-vitesse-light);background: var(--shiki-code-theme-vitesse-light-bg);font-style: var(--shiki-code-theme-vitesse-light-font-style);font-weight: var(--shiki-code-theme-vitesse-light-font-weight);text-decoration: var(--shiki-code-theme-vitesse-light-text-decoration);}html.code-theme-vitesse-light .shiki span {color: var(--shiki-code-theme-vitesse-light);background: var(--shiki-code-theme-vitesse-light-bg);font-style: var(--shiki-code-theme-vitesse-light-font-style);font-weight: var(--shiki-code-theme-vitesse-light-font-weight);text-decoration: var(--shiki-code-theme-vitesse-light-text-decoration);}html .code-theme-vitesse-dark .shiki span {color: var(--shiki-code-theme-vitesse-dark);background: var(--shiki-code-theme-vitesse-dark-bg);font-style: var(--shiki-code-theme-vitesse-dark-font-style);font-weight: var(--shiki-code-theme-vitesse-dark-font-weight);text-decoration: var(--shiki-code-theme-vitesse-dark-text-decoration);}html.code-theme-vitesse-dark .shiki span {color: var(--shiki-code-theme-vitesse-dark);background: var(--shiki-code-theme-vitesse-dark-bg);font-style: var(--shiki-code-theme-vitesse-dark-font-style);font-weight: var(--shiki-code-theme-vitesse-dark-font-weight);text-decoration: var(--shiki-code-theme-vitesse-dark-text-decoration);}html .code-theme-catppuccin-light .shiki span {color: var(--shiki-code-theme-catppuccin-light);background: var(--shiki-code-theme-catppuccin-light-bg);font-style: var(--shiki-code-theme-catppuccin-light-font-style);font-weight: var(--shiki-code-theme-catppuccin-light-font-weight);text-decoration: var(--shiki-code-theme-catppuccin-light-text-decoration);}html.code-theme-catppuccin-light .shiki span {color: var(--shiki-code-theme-catppuccin-light);background: var(--shiki-code-theme-catppuccin-light-bg);font-style: var(--shiki-code-theme-catppuccin-light-font-style);font-weight: var(--shiki-code-theme-catppuccin-light-font-weight);text-decoration: var(--shiki-code-theme-catppuccin-light-text-decoration);}html .code-theme-catppuccin-dark .shiki span {color: var(--shiki-code-theme-catppuccin-dark);background: var(--shiki-code-theme-catppuccin-dark-bg);font-style: var(--shiki-code-theme-catppuccin-dark-font-style);font-weight: var(--shiki-code-theme-catppuccin-dark-font-weight);text-decoration: var(--shiki-code-theme-catppuccin-dark-text-decoration);}html.code-theme-catppuccin-dark .shiki span {color: var(--shiki-code-theme-catppuccin-dark);background: var(--shiki-code-theme-catppuccin-dark-bg);font-style: var(--shiki-code-theme-catppuccin-dark-font-style);font-weight: var(--shiki-code-theme-catppuccin-dark-font-weight);text-decoration: var(--shiki-code-theme-catppuccin-dark-text-decoration);}html .code-theme-one-light .shiki span {color: var(--shiki-code-theme-one-light);background: var(--shiki-code-theme-one-light-bg);font-style: var(--shiki-code-theme-one-light-font-style);font-weight: var(--shiki-code-theme-one-light-font-weight);text-decoration: var(--shiki-code-theme-one-light-text-decoration);}html.code-theme-one-light .shiki span {color: var(--shiki-code-theme-one-light);background: var(--shiki-code-theme-one-light-bg);font-style: var(--shiki-code-theme-one-light-font-style);font-weight: var(--shiki-code-theme-one-light-font-weight);text-decoration: var(--shiki-code-theme-one-light-text-decoration);}html .code-theme-one-dark .shiki span {color: var(--shiki-code-theme-one-dark);background: var(--shiki-code-theme-one-dark-bg);font-style: var(--shiki-code-theme-one-dark-font-style);font-weight: var(--shiki-code-theme-one-dark-font-weight);text-decoration: var(--shiki-code-theme-one-dark-text-decoration);}html.code-theme-one-dark .shiki span {color: var(--shiki-code-theme-one-dark);background: var(--shiki-code-theme-one-dark-bg);font-style: var(--shiki-code-theme-one-dark-font-style);font-weight: var(--shiki-code-theme-one-dark-font-weight);text-decoration: var(--shiki-code-theme-one-dark-text-decoration);}html .code-theme-material-light .shiki span {color: var(--shiki-code-theme-material-light);background: var(--shiki-code-theme-material-light-bg);font-style: var(--shiki-code-theme-material-light-font-style);font-weight: var(--shiki-code-theme-material-light-font-weight);text-decoration: var(--shiki-code-theme-material-light-text-decoration);}html.code-theme-material-light .shiki span {color: var(--shiki-code-theme-material-light);background: var(--shiki-code-theme-material-light-bg);font-style: var(--shiki-code-theme-material-light-font-style);font-weight: var(--shiki-code-theme-material-light-font-weight);text-decoration: var(--shiki-code-theme-material-light-text-decoration);}html .code-theme-material-dark .shiki span {color: var(--shiki-code-theme-material-dark);background: var(--shiki-code-theme-material-dark-bg);font-style: var(--shiki-code-theme-material-dark-font-style);font-weight: var(--shiki-code-theme-material-dark-font-weight);text-decoration: var(--shiki-code-theme-material-dark-text-decoration);}html.code-theme-material-dark .shiki span {color: var(--shiki-code-theme-material-dark);background: var(--shiki-code-theme-material-dark-bg);font-style: var(--shiki-code-theme-material-dark-font-style);font-weight: var(--shiki-code-theme-material-dark-font-weight);text-decoration: var(--shiki-code-theme-material-dark-text-decoration);}html .code-theme-min-light .shiki span {color: var(--shiki-code-theme-min-light);background: var(--shiki-code-theme-min-light-bg);font-style: var(--shiki-code-theme-min-light-font-style);font-weight: var(--shiki-code-theme-min-light-font-weight);text-decoration: var(--shiki-code-theme-min-light-text-decoration);}html.code-theme-min-light .shiki span {color: var(--shiki-code-theme-min-light);background: var(--shiki-code-theme-min-light-bg);font-style: var(--shiki-code-theme-min-light-font-style);font-weight: var(--shiki-code-theme-min-light-font-weight);text-decoration: var(--shiki-code-theme-min-light-text-decoration);}html .code-theme-min-dark .shiki span {color: var(--shiki-code-theme-min-dark);background: var(--shiki-code-theme-min-dark-bg);font-style: var(--shiki-code-theme-min-dark-font-style);font-weight: var(--shiki-code-theme-min-dark-font-weight);text-decoration: var(--shiki-code-theme-min-dark-text-decoration);}html.code-theme-min-dark .shiki span {color: var(--shiki-code-theme-min-dark);background: var(--shiki-code-theme-min-dark-bg);font-style: var(--shiki-code-theme-min-dark-font-style);font-weight: var(--shiki-code-theme-min-dark-font-weight);text-decoration: var(--shiki-code-theme-min-dark-text-decoration);}html pre.shiki code .sIQTy, html code.shiki .sIQTy{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#999999;--shiki-code-theme-vitesse-dark:#666666;--shiki-code-theme-catppuccin-light:#7C7F93;--shiki-code-theme-catppuccin-dark:#9399B2;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#24292EFF;--shiki-code-theme-min-dark:#B392F0}html pre.shiki code .sOgDI, html code.shiki .sOgDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-code-theme-vitesse-light:#99841877;--shiki-code-theme-vitesse-dark:#B8A96577;--shiki-code-theme-catppuccin-light:#7C7F93;--shiki-code-theme-catppuccin-dark:#9399B2;--shiki-code-theme-one-light:#E45649;--shiki-code-theme-one-dark:#E06C75;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#D32F2F;--shiki-code-theme-min-dark:#F8F8F8}html pre.shiki code .sSdLo, html code.shiki .sSdLo{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-code-theme-vitesse-light:#998418;--shiki-code-theme-vitesse-dark:#B8A965;--shiki-code-theme-catppuccin-light:#1E66F5;--shiki-code-theme-catppuccin-dark:#89B4FA;--shiki-code-theme-one-light:#E45649;--shiki-code-theme-one-dark:#E06C75;--shiki-code-theme-material-light:#9C3EDA;--shiki-code-theme-material-dark:#C792EA;--shiki-code-theme-min-light:#D32F2F;--shiki-code-theme-min-dark:#F8F8F8}html pre.shiki code .sRS6S, html code.shiki .sRS6S{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#999999;--shiki-code-theme-vitesse-dark:#666666;--shiki-code-theme-catppuccin-light:#7C7F93;--shiki-code-theme-catppuccin-dark:#9399B2;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#212121;--shiki-code-theme-min-dark:#BBBBBB}html pre.shiki code .sLXf0, html code.shiki .sLXf0{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-code-theme-vitesse-light:#B5695977;--shiki-code-theme-vitesse-dark:#C98A7D77;--shiki-code-theme-catppuccin-light:#40A02B;--shiki-code-theme-catppuccin-dark:#A6E3A1;--shiki-code-theme-one-light:#50A14F;--shiki-code-theme-one-dark:#98C379;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#22863A;--shiki-code-theme-min-dark:#FFAB70}html pre.shiki code .sCtJb, html code.shiki .sCtJb{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-code-theme-vitesse-light:#B56959;--shiki-code-theme-vitesse-dark:#C98A7D;--shiki-code-theme-catppuccin-light:#40A02B;--shiki-code-theme-catppuccin-dark:#A6E3A1;--shiki-code-theme-one-light:#50A14F;--shiki-code-theme-one-dark:#98C379;--shiki-code-theme-material-light:#91B859;--shiki-code-theme-material-dark:#C3E88D;--shiki-code-theme-min-light:#22863A;--shiki-code-theme-min-dark:#FFAB70}html pre.shiki code .s_Zq6, html code.shiki .s_Zq6{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-code-theme-vitesse-light:#2F798A;--shiki-code-theme-vitesse-dark:#4C9A91;--shiki-code-theme-catppuccin-light:#FE640B;--shiki-code-theme-catppuccin-dark:#FAB387;--shiki-code-theme-one-light:#986801;--shiki-code-theme-one-dark:#D19A66;--shiki-code-theme-material-light:#F76D47;--shiki-code-theme-material-dark:#F78C6C;--shiki-code-theme-min-light:#1976D2;--shiki-code-theme-min-dark:#F8F8F8}html pre.shiki code .s4Bi8, html code.shiki .s4Bi8{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#999999;--shiki-code-theme-vitesse-dark:#666666;--shiki-code-theme-catppuccin-light:#179299;--shiki-code-theme-catppuccin-dark:#94E2D5;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#24292EFF;--shiki-code-theme-min-dark:#B392F0}html pre.shiki code .spV5I, html code.shiki .spV5I{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#85E89D;--shiki-code-theme-vitesse-light:#1E754F;--shiki-code-theme-vitesse-dark:#4D9375;--shiki-code-theme-catppuccin-light:#1E66F5;--shiki-code-theme-catppuccin-dark:#89B4FA;--shiki-code-theme-one-light:#E45649;--shiki-code-theme-one-dark:#E06C75;--shiki-code-theme-material-light:#E53935;--shiki-code-theme-material-dark:#F07178;--shiki-code-theme-min-light:#22863A;--shiki-code-theme-min-dark:#FFAB70}html pre.shiki code .shR_7, html code.shiki .shR_7{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-code-theme-vitesse-light:#B07D48;--shiki-code-theme-vitesse-dark:#BD976A;--shiki-code-theme-catppuccin-light:#DF8E1D;--shiki-code-theme-catppuccin-dark:#F9E2AF;--shiki-code-theme-one-light:#986801;--shiki-code-theme-one-dark:#D19A66;--shiki-code-theme-material-light:#9C3EDA;--shiki-code-theme-material-dark:#C792EA;--shiki-code-theme-min-light:#6F42C1;--shiki-code-theme-min-dark:#B392F0}html pre.shiki code .stNAY, html code.shiki .stNAY{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#999999;--shiki-code-theme-vitesse-dark:#666666;--shiki-code-theme-catppuccin-light:#179299;--shiki-code-theme-catppuccin-dark:#94E2D5;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#39ADB5;--shiki-code-theme-material-dark:#89DDFF;--shiki-code-theme-min-light:#D32F2F;--shiki-code-theme-min-dark:#F97583}html pre.shiki code .sw9Yk, html code.shiki .sw9Yk{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#393A34;--shiki-code-theme-vitesse-dark:#DBD7CAEE;--shiki-code-theme-catppuccin-light:#4C4F69;--shiki-code-theme-catppuccin-dark:#CDD6F4;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#90A4AE;--shiki-code-theme-material-dark:#BABED8;--shiki-code-theme-min-light:#24292EFF;--shiki-code-theme-min-dark:#B392F0}html pre.shiki code .sO_xl, html code.shiki .sO_xl{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#999999;--shiki-code-theme-vitesse-dark:#666666;--shiki-code-theme-catppuccin-light:#7C7F93;--shiki-code-theme-catppuccin-dark:#9399B2;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#91B859;--shiki-code-theme-material-dark:#C3E88D;--shiki-code-theme-min-light:#2B5581;--shiki-code-theme-min-dark:#9DB1C5}html pre.shiki code .ssTbb, html code.shiki .ssTbb{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#393A34;--shiki-code-theme-vitesse-dark:#DBD7CAEE;--shiki-code-theme-catppuccin-light:#04A5E5;--shiki-code-theme-catppuccin-dark:#89DCEB;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#90A4AE90;--shiki-code-theme-material-dark:#BABED890;--shiki-code-theme-min-light:#2B5581;--shiki-code-theme-min-dark:#9DB1C5}html pre.shiki code .sMLmi, html code.shiki .sMLmi{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-code-theme-vitesse-light:#393A34;--shiki-code-theme-vitesse-dark:#DBD7CAEE;--shiki-code-theme-catppuccin-light:#4C4F69;--shiki-code-theme-catppuccin-dark:#CDD6F4;--shiki-code-theme-one-light:#383A42;--shiki-code-theme-one-dark:#ABB2BF;--shiki-code-theme-material-light:#90A4AE90;--shiki-code-theme-material-dark:#BABED890;--shiki-code-theme-min-light:#2B5581;--shiki-code-theme-min-dark:#9DB1C5}",{"title":542,"searchDepth":561,"depth":561,"links":946},[947,948,949,950,956],{"id":433,"depth":561,"text":433},{"id":450,"depth":561,"text":451},{"id":466,"depth":561,"text":467},{"id":488,"depth":561,"text":489,"children":951},[952,953,954,955],{"id":513,"depth":567,"text":513},{"id":691,"depth":567,"text":692},{"id":859,"depth":567,"text":859},{"id":883,"depth":567,"text":883},{"id":913,"depth":561,"text":913},null,"2026-10-04","修好首页的巡检文档入口，更新依赖和发布检查，再用几个实际例子看看新增的 MDC 组件。","md","\u002Fimages\u002Fmdc\u002Frender-flow.svg",{},{"icon":247},"---\ntitle: 最近给文档站补了些什么\ndescription: 修好首页的巡检文档入口，更新依赖和发布检查，再用几个实际例子看看新增的 MDC 组件。\ndate: '2026-10-04'\nimg: \u002Fimages\u002Fmdc\u002Frender-flow.svg\nnavigation:\n  icon: lucide:blocks\ntags:\n  - Estel Docs\n  - Nuxt\n  - MDC\n---\n\n这两天更新了文档站的依赖，也把首页入口、内容渲染和发布检查重新过了一遍。改动比较散，单看提交记录不太好找，放在这里记一下。\n\n其中一个问题很直观：从首页点“文档”，再选巡检工具，明明内容文件在，却进不去。这个入口已经修好。后面又补了一批 MDC 组件，文档和博客都能直接用，下面顺带放几个例子。\n\n## 先把点不开的文档修好\n\n问题出在路径解析。浏览器中的 URL 和内容库记录的路径没有统一处理，中文编码、大小写和末尾斜杠混在一起，查询时就可能找不到对应页面。\n\n现在先规范路径，再查询内容。巡检工具的首页入口、文档内部跳转、直接刷新和原始 Markdown 页面一起检查过，避免只修好其中一个入口。\n\n顺手也核对了草稿的发布行为。生产构建会排除标记为 `draft: true` 的内容，导航、搜索和 Feed 等公开入口跟着使用公开内容。写到一半的稿子，就先留在草稿里。\n\n## 依赖更新了，但没有硬追版本号\n\n这次把 Nuxt、Content、UI 和测试工具等依赖更新了一轮。当前主框架是 Nuxt 4.5.2、Nuxt Content 3.16.1、Nuxt UI 4.11.3，包管理器使用 pnpm 12.8.1。\n\nTypeScript 暂时留在 6.0.3。尝试升级到 7 时，ESLint 和 Vue 类型检查遇到了兼容问题，先退回能通过检查的版本。这件事留了工单，等工具链跟上再处理。\n\n生产检查也补了些过去容易漏掉的地方：代码检查、内容链接、类型、单元测试、构建后的页面测试，以及 Go 微信签名服务的检查。Docker 增加健康检查，CI 里还会实际启动容器，确认内容查询和图片处理能跑。\n\n这里记的是仓库里的改动，线上效果还要等发布后确认。\n\n## 页面看起来正常，也可能藏着渲染问题\n\n这次还修了图片、示例标题和公式样式的几个小问题。有些 HTML 结构浏览器会自行纠正，肉眼看不出来，但 Vue 接管页面时就可能发现前后结构对不上。\n\n这里的 :glossary-term{term=\"Hydration\" definition=\"浏览器中的 Vue 接管服务端生成的 HTML，为页面连接事件和响应式状态。\"}，就是服务端页面交到浏览器后的那一步。\n\n图片容器和标题示例的结构调整后，服务端与浏览器保持一致；MathJax 生成的样式也单独处理了。代码主题、行号和图注设置则接上了实际渲染，刷新后会恢复已保存的选项。\n\n另外，Studio 的生产入口现在默认关闭。需要在线编辑时再按部署说明启用，把 OAuth 和会话密钥放在运行环境里。\n\n## 新组件，先从能用上的几个说起\n\n以前写设备清单、参数说明，基本都靠普通表格。内容少的时候够用，行数一多，找东西就得来回翻。现在有了 `DataTable`，表格里能搜索、排序和分页。\n\n下面把这次改动列成一张表。试着搜“组件”，或者点“类别”排序；清空搜索后可以翻页。\n\n::data-table\n---\ntitle: 本次改动速查\npageSize: 4\ncolumns:\n  - key: area\n    label: 类别\n  - key: change\n    label: 改动\n  - key: detail\n    label: 现在的行为\nrows:\n  - area: 文档入口\n    change: 统一路径解析\n    detail: 首页巡检文档入口、刷新和原始 Markdown 查询使用相同规则\n  - area: 内容发布\n    change: 排除生产草稿\n    detail: 草稿不进入公开内容集合\n  - area: 页面渲染\n    change: 调整图片、标题和公式样式\n    detail: 修复相关服务端与客户端渲染不一致的问题\n  - area: 阅读设置\n    change: 联动代码主题、行号和图注\n    detail: 设置影响页面渲染，刷新后恢复选项\n  - area: 内容组件\n    change: 增加文章排版组件\n    detail: 摘要、折叠说明、时间线、清单和图库可直接写入 Markdown\n  - area: 内容组件\n    change: 增加数据与阅读交互组件\n    detail: 参数表、数据表、图片对比、术语、自测和下载入口\n  - area: 生产部署\n    change: 收紧 Studio 配置并增加容器检查\n    detail: 编辑入口按需启用，镜像通过检查后再发布\n---\n::\n\n数据还是写在 Markdown 里，组件只负责页面内的查找和展示。没有给这个表另外接一个接口。\n\n### 接口说明不用拆成几张表\n\n`ApiEndpoint` 和 `ParameterTable` 可以放在一起。拿仓库已有的微信签名接口举个例子，方法、路径、参数和请求响应都放在一个块里：\n\n:::api-endpoint{title=\"获取微信 JS-SDK 签名\" method=\"POST\" path=\"\u002Fapi\u002Fwechat\u002Fjs-sign\" :status=\"200\"}\n这是独立 Go 服务提供的接口，需部署服务并配置允许的来源和签名域名。这里只展示格式，响应中的值是占位示例，不能用于微信初始化。\n\n::parameter-table\n---\ntitle: 请求参数\nparameters:\n  - name: url\n    type: string\n    location: body\n    required: true\n    description: 需要签名的页面完整地址；域名需在服务端白名单中，hash 会被移除\n---\n::\n\n#request\n```http\nPOST \u002Fapi\u002Fwechat\u002Fjs-sign HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{ \"url\": \"https:\u002F\u002Flijue.net\u002Fdocs\" }\n```\n\n#response\n```json\n{\n  \"appId\": \"wx-example\",\n  \"timestamp\": 1791043200,\n  \"nonceStr\": \"example-nonce\",\n  \"signature\": \"example-signature\"\n}\n```\n:::\n\n这个组件不会请求上面的接口。它解决的是“说明怎么排”，真要测试接口，还是用自己的客户端或命令行。\n\n### 长说明可以收起来，源码也能放进去\n\n`ExpandBox` 是一个折叠块。参数不多时把代码放进去，正文就不用同时铺开效果和源码。点开下面这段，可以复制一个最小的接口说明：\n\n::expand-box{title=\"查看 ApiEndpoint 的 MDC 写法\"}\n````mdc\n:::api-endpoint{title=\"查询示例报告\" method=\"GET\" path=\"\u002Fapi\u002Freports\u002F{id}\" :status=\"200\"}\n这是一个虚构接口，仅用于说明布局。\n\n#request\n```http\nGET \u002Fapi\u002Freports\u002Fdemo HTTP\u002F1.1\n```\n\n#response\n```json\n{ \"id\": \"demo\", \"status\": \"ready\" }\n```\n:::\n````\n::\n\n组件名用短横线写，嵌套时外层多一个冒号。上面的 `#request` 和 `#response` 是插槽名，不是文章标题。\n\n### 示例文件有个明确的下载位置\n\n文章里附配置片段，读者有时想直接拿文件改。`DownloadCard` 可以把文件名和用途放在链接旁边：\n\n::download-card{title=\"设备清单示例 JSON\" href=\"\u002Fexamples\u002Fdevices.example.json\" filename=\"devices.example.json\" description=\"两条文档示例地址，不含账号密码；字段需按实际工具格式调整。\"}\n::\n\n这个文件用来演示下载，不是巡检工具的正式配置模板。文件放在 `public\u002F` 中，卡片指向它已有的地址。\n\n### 操作指南可以加一份核对清单\n\n清单能勾选，也能看到完成了几项。写部署说明、故障排查记录时，放在最后比较合适。\n\n::task-checklist\n---\ntitle: 写完一篇带组件的文章后\nitems:\n  - label: 打开页面，确认效果和源码一致\n  - label: 用手机宽度试一下表格和参数说明\n  - label: 点开下载，确认拿到的是示例文件\n---\n::\n\n勾选只保留在当前页面，刷新就恢复初始状态。如果需要长期记录执行结果，那是另一项功能。\n\n`ContentQuiz` 也采用相同的页面内交互方式，适合教程里的小题。比如检查一下刚才的插槽写法：\n\n::content-quiz\n---\nquestion: ApiEndpoint 中的响应示例应该放在哪个插槽？\nchoices:\n  - request\n  - response\n  - takeaway\nanswer: 1\nexplanation: response 放响应示例，request 放请求示例；takeaway 是 ArticleSummary 的插槽。\n---\n::\n\n答案写在公开内容里，组件只给阅读反馈，不记录成绩。\n\n## 说明也一起补上了\n\n这轮还加了摘要、链接卡片、引用、数字概览、时间线、图库和图片对比。连同原来的卡片、标签页、文件树等，目前有 27 个公共自定义组件。普通段落能说明白的地方，仍然直接写 Markdown，不需要每一节都套卡片。\n\n“简单文档”里补了一篇 [在文章中使用组件](\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmdc-content)，把效果和可复制的代码放在一起。查参数可以看 [常用组件](\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fapi)，想试图库、图片对比等交互，就去 [内容组件演示](\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fmdc-showcase) 和 [进阶组件演示](\u002Fdocs\u002F简单文档\u002Fcomponents\u002Finteractive-showcase)。\n\n后面写巡检工具说明、排障记录和配置指南时，就可以直接用这些现成的块了。\n",{"title":244,"description":959},[967,968,969],"Estel Docs","Nuxt","MDC","B4DwWpRVVaRNrP5Q0qTFwARelhVjI2-81UBbb7I744k",[957,972],{"title":249,"path":250,"stem":251,"description":973,"icon":252,"children":-1},"记录一次银河麒麟终端中 Windows 虚拟环境因 IP 地址不符合网络准入规则，导致安全桌面认证和办公 OA 登录失败的完整排查过程。",1791307024991]