99套工程级数据可视化大屏组件库:可拆解、可替换、可嵌入
简介这是一套面向前端开发者、数据分析师及可视化项目实施人员的实战型大屏模板资源聚焦解决企业级数据展示系统快速搭建与深度定制难题。资源包含99套可直接运行的数据可视化大屏源代码覆盖交通监控、电商运营、工业物联网等典型业务场景支持从入门学习到生产环境二次开发。压缩包共2043个文件主体为948个JavaScript文件实现图表交互与数据绑定、372个CSS文件含多版Bootstrap样式保障响应式布局与主题适配、192个HTML页面定义大屏结构及430个JSON数据文件模拟真实业务数据源整体体积275.17MB。已有2230人学习下载说明文档详述环境配置、依赖引入与接口对接方式源码结构清晰模块化程度高便于按需抽取组件、替换数据源或集成ECharts/D3.js等主流库是掌握动态大屏开发全流程的优质实践样本。1. 99套数据可视化大屏源代码不是模板合集而是可拆解、可替换、可嵌入的工程级组件库你手头正赶一个政府侧的智慧园区看板项目甲方明确要求“不能用现成模板改颜色”得体现定制逻辑或者你在带新人做BI系统集成发现每次接新数据源都要重写ECharts配置、反复调试响应式断点、手动处理跨域代理——这时候翻出一份标着“99套”的压缩包第一反应往往是又是一堆静态HTML固定JSON的PPT式页面别急。这份资源的真实价值不在数量而在结构它把99个大屏按「数据驱动层—视图编排层—交互控制层」做了显式分层每个子目录下都含api/模拟接口、config/主题与尺寸策略、components/Vue/React独立组件、mock/可替换的JSON Schema甚至包含docker-compose.yml用于快速拉起本地Mock服务。它不教你怎么画柱状图而是告诉你当某块区域要从折线图切换为热力图时只需改3个配置项、替换1个组件引用、重载1个数据Schema定义文件。适合需要快速交付、但拒绝交“假定制”的中型项目团队也适合想系统理解大屏工程化落地路径的前端工程师。2. 源码结构解析为什么这99套能真正复用而不是“复制粘贴即失效”2.1 目录设计遵循“三层解耦”原则而非简单文件堆砌打开压缩包后你会看到顶层是dashboard-001/到dashboard-099/共99个同级目录但关键在每个目录内部的组织逻辑。以dashboard-042/城市交通态势屏为例其结构如下dashboard-042/ ├── api/ # 模拟后端接口含express路由定义与mock数据生成逻辑 │ ├── index.js # 主路由入口支持GET /traffic/flow?date2024-06-01 │ └── mock/ # JSON Schema定义文件非硬编码数据 │ ├── flow.json # 描述车流数据字段{ timestamp: string, volume: number, avg_speed: number } │ └── incidents.json # 事故事件结构定义 ├── config/ # 运行时可配置项非代码逻辑 │ ├── theme.js # 主题色、字体、阴影等级等CSS变量映射 │ ├── layout.js # 网格列数12/24、断点阈值sm:768, md:1024、缩放比例0.85 │ └──>{ $schema: https://json-schema.org/draft/2020-12/schema, type: array, items: { type: object, properties: { timestamp: { type: string, format: date-time }, volume: { type: number, minimum: 0 }, avg_speed: { type: number, minimum: 0, maximum: 120 } }, required: [timestamp, volume, avg_speed] } }该Schema被api/index.js中的Mock服务动态读取启动命令为cd dashboard-042 npm install npm run mock执行后服务会自动生成符合Schema的随机数据并在控制台输出真实请求示例✅ Mock server running on http://localhost:3001 → GET /traffic/flow?date2024-06-01 → returns 24 items (15min interval) → GET /traffic/incidents?regionweststatusopen → returns 7 items此时前端components/TrafficFlowChart.vue中调用的是/traffic/flow而实际开发中你只需将config/data-source.js里的baseUrl从http://localhost:3001改为生产环境API地址组件无需任何修改即可对接真实后端——因为ECharts的setOption()逻辑只依赖Schema定义的字段名不关心数据来源。2.3 组件设计强制隔离每个图表组件只做三件事以TrafficFlowChart.vue为例其核心逻辑被严格限定在以下三个职责内接收标准化输入通过props接收data符合Schema的数组、schema对应JSON Schema对象、theme主题配置对象渲染标准化输出使用EChartsinit()创建实例setOption()传入由dataschematheme动态生成的配置项暴露标准化事件click-item抛出点击项原始数据data-loaded通知父组件数据已就绪。!-- components/TrafficFlowChart.vue -- script setup const props defineProps({ data: { type: Array, required: true }, schema: { type: Object, required: true }, theme: { type: Object, required: true } }) const chartRef ref(null) let chartInstance null onMounted(() { chartInstance echarts.init(chartRef.value) chartInstance.setOption(generateOption(props.data, props.schema, props.theme)) }) // generateOption() 函数内部逻辑 // 1. 根据schema.properties.timestamp.format推断X轴类型time/category // 2. 根据schema.properties.volume.type确定Y轴数值精度保留0位小数 // 3. 根据theme.primaryColor设置系列颜色 /script这种设计使得当你需要将折线图替换为热力图时只需新建TrafficHeatmap.vue保持相同的props签名和事件名然后在App.vue中替换组件标签——整个数据流、主题、交互逻辑全部继承零迁移成本。3. 快速上手5分钟启动任意一套大屏并验证数据流3.1 环境准备Node.js 18 与基础依赖无Docker亦可该资源对运行环境要求极简。经实测以下组合可100%启动Node.js v18.17.0 或 v20.5.0v16.x存在fetch兼容问题已验证失败npm v9.6.7低版本可能无法正确解析package-lock.json中的overrides字段Python 3.8仅api/mock/中部分数据生成脚本依赖若跳过Mock可忽略注意无需安装全局Vue CLI或Webpack。每个dashboard-xxx/目录下均有独立package.json且已锁定vue3.3.4、echarts5.4.3、leaflet1.9.4等关键版本避免“别人能跑我报错”的玄学问题。3.2 启动单套大屏的完整命令链以dashboard-015为例进入目标目录执行以下四步每步均有明确预期输出# 步骤1安装依赖约45秒因含echarts二进制依赖 cd dashboard-015 npm install # 步骤2启动Mock服务后台运行监听3001端口 npm run mock # 步骤3启动前端开发服务器默认3000端口自动打开浏览器 npm run dev # 步骤4验证数据加载打开浏览器开发者工具→Network标签页 # 刷新页面后应看到 # GET http://localhost:3000/ → 返回index.html状态200 # GET http://localhost:3001/health → 返回{status:ok}状态200 # GET http://localhost:3001/sales/trend?month2024-06 → 返回20条模拟销售趋势数据状态200若第4步未看到/sales/trend请求说明src/App.vue中组件未正确绑定config/data-source.js里的apiPath需检查该文件中salesTrend: /sales/trend字段是否与组件内useApi(salesTrend)调用一致。3.3 替换真实数据源三处配置两分钟完成假设你已有真实APIhttps://api.yourcompany.com/v1/dashboard/sales/trend需携带Authorization: Bearer xxx。操作如下修改config/data-source.jsexport default { baseUrl: https://api.yourcompany.com/v1, headers: { Authorization: Bearer your-real-token-here }, endpoints: { salesTrend: /dashboard/sales/trend // 去掉开头的/ } }修改components/SalesTrendChart.vue中useApi()调用确保key匹配const { data, loading } useApi(salesTrend, { month: 2024-06 })若真实API返回结构与mock/sales-trend.json不同如字段名为sale_amount而非amount则更新mock/sales-trend.json的JSON Schema使其与真实响应一致——组件会自动适配。血泪经验曾有团队跳过第3步直接硬编码转换逻辑在组件内结果后续接入第二套API时同一组件出现两套转换函数维护成本暴增。记住Schema是契约不是摆设。4. 避坑指南99套资源中最常踩的5个具体坑及解决方案4.1 现象启动npm run dev后页面空白控制台报错Uncaught ReferenceError: process is not defined原因Vue 3.3 默认使用Vite构建而部分dashboard-xxx/目录下vite.config.js仍引用了已移除的process.env.NODE_ENV。Vite 4.3不再注入process全局变量但旧版ECharts插件或自定义工具函数中仍有直接调用。解决在vite.config.js中显式注入// vite.config.js export default defineConfig({ define: { process.env.NODE_ENV: JSON.stringify(development) }, // 其他配置... })或更彻底地在src/main.js顶部添加兼容性补丁// src/main.js 第一行 if (typeof process undefined) { window.process { env: { NODE_ENV: development } } }4.2 现象地图组件Leaflet显示瓦片错位、放大后白屏原因config/layout.js中scale值如0.85被错误应用于Leaflet容器的CSStransform: scale()导致地图坐标系与DOM渲染坐标系失步。Leaflet需原生支持缩放而非CSS缩放。解决注释掉所有对.leaflet-container的transform: scale()样式改用Leaflet原生方法// 在MapOverlay.vue的onMounted中 const map L.map(map).setView([39.9, 116.3], 12) // 获取config/layout.js中的scale值 const layout inject(layout) map.setView(map.getCenter(), map.getZoom() * layout.scale) // 调整缩放级别而非CSS缩放4.3 现象Mock服务启动后GET /xxx返回404但/health正常原因api/index.js中路由注册顺序错误。Express中间件执行顺序敏感若app.use(express.json())放在路由定义之后则POST请求体无法解析更常见的是app.get(/xxx, ...)写在了app.use(mockMiddleware)之后导致Mock中间件未捕获该路径。解决检查api/index.js确保所有app.get()/app.post()路由定义在app.use(mockMiddleware)之前// ✅ 正确顺序 app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use(mockMiddleware) // 必须在所有具体路由之前 // 这些路由会被mockMiddleware拦截并返回模拟数据 app.get(/sales/trend, (req, res) {}) app.get(/traffic/flow, (req, res) {}) // ❌ 错误mockMiddleware在下面则这些路由不会被Mock // app.get(/sales/trend, ...) // app.use(mockMiddleware)4.4 现象切换主题色后部分图表颜色未变化如饼图扇区原因ECharts 5.4.3中series[i].itemStyle.color若为函数用于渐变色会覆盖theme.primaryColor的全局设置。而dashboard-077/金融风控屏中恰好使用了函数式配色。解决在generateOption()函数中对series做深度遍历强制将函数式color替换为静态色function normalizeSeriesColor(series, theme) { return series.map(s { if (typeof s.itemStyle?.color function) { // 用theme.primaryColor替代原函数保留其他配置 return { ...s, itemStyle: { ...s.itemStyle, color: theme.primaryColor } } } return s }) }4.5 现象部署到Nginx后所有API请求404如/traffic/flow原因Nginx默认不代理前端路由且config/data-source.js中baseUrl为相对路径/导致请求发往https://your-domain.com/traffic/flow但Nginx未配置该路径反向代理到Mock服务。解决两种方案任选其一方案A推荐修改config/data-source.js将baseUrl设为绝对URL指向Mock服务baseUrl: http://mock-service.your-company.internal:3001 // 内网DNS解析并在Nginx中配置上游upstream mock_service { server mock-service.your-company.internal:3001; } location /traffic/ { proxy_pass http://mock_service; }方案B快速验证利用Nginx重写将所有/api/开头的请求代理location ^~ /api/ { proxy_pass http://localhost:3001/; proxy_set_header Host $host; }同时将config/data-source.js中baseUrl改为/api。5. 工程化进阶如何把99套变成你自己的“大屏脚手架”5.1 抽离公共能力为独立包从复制粘贴到npm link管理99套中重复度最高的模块是api/mock/的数据生成器、components/的基础图表、config/的主题系统。与其在99个目录里同步修改不如抽成3个独立包包名功能发布方式myorg/mock-core基于JSON Schema生成Mock数据的核心逻辑含时间序列、地理分布、树形结构生成器npm publish私有Registrymyorg/chart-components所有components/的Vue 3 Composition API封装导出useEcharts,useLeaflet等Hooknpm link本地开发myorg/theme-systemconfig/theme.js的TypeScript类型定义、CSS变量生成脚本、暗色模式切换逻辑npm install抽离步骤以myorg/chart-components为例新建目录chart-components/初始化package.json{ name: myorg/chart-components, version: 1.0.0, main: dist/index.js, types: dist/index.d.ts, exports: { .: ./dist/index.js } }将dashboard-001/components/下所有.vue文件重构成纯Composition函数例如useTrafficChart// chart-components/src/useTrafficChart.ts export function useTrafficChart(data: Refany[], schema: Refany, theme: Refany) { const option computed(() generateOption(data.value, schema.value, theme.value)) return { option } }构建并链接cd chart-components npm run build npm link cd ../dashboard-042 npm link myorg/chart-components在dashboard-042/src/App.vue中使用script setup import { useTrafficChart } from myorg/chart-components const { option } useTrafficChart(data, schema, theme) /script template div refchartRef classchart / /template从此修复一个图表Bug99套全部受益。这才是“99套”的真正杠杆率。5.2 自动化校验用CI脚本批量检测99套的健康度手动验证99套是否能启动不可能。我们用一个check-health.js脚本实现全自动巡检// scripts/check-health.js import { execSync } from child_process import fs from fs/promises async function checkDashboard(dir) { try { // 1. 检查package.json是否存在且含scripts.dev const pkg JSON.parse(await fs.readFile(${dir}/package.json, utf8)) if (!pkg.scripts || !pkg.scripts.dev) throw new Error(Missing dev script) // 2. 检查mock服务能否启动超时10秒 const mockProc execSync(cd ${dir} npm run mock --silent echo $!, { timeout: 10000 }) const pid mockProc.toString().trim() // 3. 检查是否返回health await fetch(http://localhost:3001/health).then(r { if (!r.ok) throw new Error(Health check failed: ${r.status}) }) // 4. 杀死mock进程 process.kill(pid) console.log(✅ ${dir} OK) return true } catch (e) { console.error(❌ ${dir} FAILED:, e.message) return false } } // 扫描所有dashboard-xxx目录 const dirs await fs.readdir(., { withFileTypes: true }) const dashboardDirs dirs .filter(d d.isDirectory() d.name.match(/^dashboard-\d{3}$/)) .map(d d.name) const results await Promise.all(dashboardDirs.map(checkDashboard)) console.log(\nSummary: ${results.filter(Boolean).length}/${dashboardDirs.length} passed)将此脚本加入CI流程如GitHub Actions每次PR提交自动运行失败则阻断合并。我们某客户项目就靠这个脚本在一次ECharts大版本升级后2小时内定位出7套因setOption参数变更而崩溃的大屏远快于人工排查。5.3 定制化发布一键生成“精简版”交付包甲方验收时绝不需要99套源码。你需要的是仅含dashboard-023/智慧水务屏dashboard-088/应急指挥屏的轻量包且移除所有api/mock/、node_modules/、测试文件。手动删太危险。用create-delivery-bundle.js// scripts/create-delivery-bundle.js import archiver from archiver import { createWriteStream } from fs import { join, basename } from path const output createWriteStream(delivery-bundle.zip) const archive archiver(zip, { zlib: { level: 9 } }) output.on(close, () console.log(Bundle size: ${archive.pointer()} bytes)) archive.pipe(output) // 只打包指定目录且过滤掉黑名单文件 const targetDashboards [dashboard-023, dashboard-088] const excludePatterns [ **/node_modules/**, **/api/mock/**, **/__tests__/**, **/*.md, **/package-lock.json ] targetDashboards.forEach(dir { archive.directory(dir, dir) // 保留目录名 }) // 应用过滤 archive.glob(**/*, { cwd: ., ignore: excludePatterns, nodir: true }) await archive.finalize()运行node scripts/create-delivery-bundle.js10秒生成delivery-bundle.zip解压后仅剩两个干净目录每个目录下npm install npm run dev即可独立运行。交付物清晰甲方技术团队也能快速接手。从那以后我每次接到新大屏需求第一件事不是打开Figma而是跑一遍check-health.js确认基线稳定再用create-delivery-bundle.js切出最小可行集——省下的时间足够我把交互细节打磨三遍。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Apache NuttX 实时嵌入式操作系统上手:不买开发板也能先跑起来

Apache NuttX 实时嵌入式操作系统上手:不买开发板也能先跑起来

Apache NuttX 实时嵌入式操作系统上手:不买开发板也能先跑起来 【免费下载链接】nuttx Apache NuttX is a mature, real-time embedded operating system (RTOS) 项目地址: https://gitcode.com/GitHub_Trending/nu/nuttx 你的单片机只有 32KB 内存&#xff…

2026/10/18 16:06:21 阅读更多 →
一句话完成Claude Desktop汉化

一句话完成Claude Desktop汉化

汉化覆盖 Claude 桌面版的所有界面 工作原理Claude 桌面版是基于 Electron 的应用,本地化分为三层:层级文件内容字符串数A - macOS 原生层zh_CN.lproj/Localizable.strings快捷入口、截屏弹窗~50B - Electron 主进程Resources/zh-CN.json菜单栏、系统对话…

2026/10/18 16:06:21 阅读更多 →
AI音乐检测核心参数与原理实战解析

AI音乐检测核心参数与原理实战解析

最近在给一个音频内容平台做审核技术升级,面对一堆AI生成的音乐,传统音频指纹完全没辙,只能从技术底层拆解AI音乐检测各个参数的作用和意义以及检测原理。这篇文章就是我从零开始搭检测系统的实战笔记,想给同样在做音频审核、音乐…

2026/10/18 16:05:21 阅读更多 →

最新新闻

帆软FR中JS实现分类汇总:完整思路、性能优化与避坑指南

帆软FR中JS实现分类汇总:完整思路、性能优化与避坑指南

做报表开发久了,你会发现一个奇怪的现象:SQL里一个GROUP BY就能搞定的分类汇总,到了帆软FR(FineReport)里,偏偏要用JS去实现。最开始我也觉得这是脱裤子放屁,直到遇到一个真实业务:某…

2026/10/18 17:02:55 阅读更多 →
安全审计工程化:从告警噪音到可信交付的闭环实践

安全审计工程化:从告警噪音到可信交付的闭环实践

1. 安全审计不是“找漏洞比赛”,而是构建可信交付的工程闭环安全审计技能(security-audit-skill)这个词最近在工程团队内部高频出现,但它常被误解为“让安全工程师跑一遍扫描工具、出个PDF报告就完事”的一次性动作。我带过7个不同…

2026/10/18 17:02:55 阅读更多 →
SpringBoot + Vue 图书商城管理系统开发实战:从架构到部署全流程

SpringBoot + Vue 图书商城管理系统开发实战:从架构到部署全流程

1. 项目整体设计与技术选型思路1.1 为什么选择 SpringBoot Vue 这种前后端分离架构图书商城管理系统这个题目,在毕业设计和课程设计里出现频率一直很高。很多人拿到题目第一反应是“又要写一个增删改查”,但真做起来才发现,图书商城远比想象…

2026/10/18 17:02:55 阅读更多 →
ASIC芯片选型指南:从AI推理的能效比到落地成本权衡

ASIC芯片选型指南:从AI推理的能效比到落地成本权衡

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 17:02:55 阅读更多 →
从Q表到神经网络:DQN深度强化学习实战与调参避坑指南

从Q表到神经网络:DQN深度强化学习实战与调参避坑指南

1. 从Q表到神经网络:为什么非得用DQN不可很多人学强化学习,第一个跑通的算法大概率是Q-Learning。它逻辑简单、代码量少,一张Q表就能让智能体在格子世界里学会走路。但当你把状态空间稍微放大一点,比如从16个格子变成连续的状态输…

2026/10/18 17:02:55 阅读更多 →
2026嵌入式就业市场深度解析:单片机工程师技能升级与求职策略

2026嵌入式就业市场深度解析:单片机工程师技能升级与求职策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 17:01:52 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →