@jet-w/astro-blog 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-FXPGR372.js +0 -0
- package/dist/chunk-GYLSY3OJ.js +173 -0
- package/dist/config/index.d.ts +166 -0
- package/dist/config/index.js +38 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +59 -0
- package/dist/types/index.d.ts +75 -0
- package/dist/types/index.js +1 -0
- package/package.json +84 -0
- package/src/components/EChartsCard.vue +118 -0
- package/src/components/Mermaid.vue +73 -0
- package/src/components/about/ContentCard.astro +27 -0
- package/src/components/about/IconCard.astro +77 -0
- package/src/components/about/SocialLinks.astro +54 -0
- package/src/components/about/TagCard.astro +65 -0
- package/src/components/about/TagGroup.astro +33 -0
- package/src/components/about/TimelineCard.astro +52 -0
- package/src/components/blog/FloatingToc.vue +198 -0
- package/src/components/blog/Hero.astro +147 -0
- package/src/components/blog/NavigationTabs.vue +245 -0
- package/src/components/blog/PostCard.astro +161 -0
- package/src/components/blog/PostNavigation.astro +106 -0
- package/src/components/blog/RelatedPosts.astro +175 -0
- package/src/components/blog/TableOfContents.astro +153 -0
- package/src/components/blog/TagCloud.astro +91 -0
- package/src/components/home/FeaturedPostsSection.astro +54 -0
- package/src/components/home/QuickNavSection.astro +81 -0
- package/src/components/home/RecentPostsSection.astro +52 -0
- package/src/components/home/StatsSection.astro +44 -0
- package/src/components/layout/Footer.astro +103 -0
- package/src/components/layout/Header.astro +68 -0
- package/src/components/layout/Sidebar.astro +594 -0
- package/src/components/media/Bilibili.astro +114 -0
- package/src/components/media/Slides.astro +313 -0
- package/src/components/media/Video.astro +111 -0
- package/src/components/media/VideoPlayer.astro +89 -0
- package/src/components/media/YouTube.astro +92 -0
- package/src/components/pte/StudyCalendar.vue +1348 -0
- package/src/components/ui/Icon.astro +187 -0
- package/src/components/ui/MobileMenu.vue +201 -0
- package/src/components/ui/Pagination.astro +143 -0
- package/src/components/ui/SearchBox.vue +179 -0
- package/src/components/ui/SearchInterface.vue +409 -0
- package/src/components/ui/SidebarToggle.vue +57 -0
- package/src/components/ui/ThemeToggle.vue +90 -0
- package/src/layouts/AboutLayout.astro +18 -0
- package/src/layouts/BaseLayout.astro +362 -0
- package/src/layouts/PageLayout.astro +217 -0
- package/src/layouts/SlidesLayout.astro +320 -0
- package/src/plugins/rehype-clean-containers.mjs +24 -0
- package/src/plugins/rehype-relative-links.mjs +43 -0
- package/src/plugins/rehype-tabs.mjs +116 -0
- package/src/plugins/remark-containers.mjs +407 -0
- package/src/plugins/remark-mermaid.mjs +46 -0
- package/src/styles/global.css +870 -0
- package/src/styles/slides.css +220 -0
- package/src/utils/sidebar.ts +492 -0
- package/templates/default/astro.config.mjs +51 -0
- package/templates/default/content/pages/about.mdx +93 -0
- package/templates/default/content/pages/index.mdx +20 -0
- package/templates/default/content/posts/blog_docs/01-quick-start.md +162 -0
- package/templates/default/content/posts/blog_docs/02-frontmatter.md +277 -0
- package/templates/default/content/posts/blog_docs/03-markdown-basic.md +350 -0
- package/templates/default/content/posts/blog_docs/04-containers.md +331 -0
- package/templates/default/content/posts/blog_docs/05-code-blocks.md +388 -0
- package/templates/default/content/posts/blog_docs/06-mermaid.md +431 -0
- package/templates/default/content/posts/blog_docs/07-video.md +243 -0
- package/templates/default/content/posts/blog_docs/08-latex.md +382 -0
- package/templates/default/content/posts/blog_docs/09-icons.md +326 -0
- package/templates/default/content/posts/blog_docs/10-sidebar.md +445 -0
- package/templates/default/content/posts/blog_docs/11-config.md +334 -0
- package/templates/default/content/posts/blog_docs/12-slides.mdx +552 -0
- package/templates/default/content/posts/blog_docs/README.md +151 -0
- package/templates/default/content/slides/demo.md +146 -0
- package/templates/default/content/slides/docs/basic-demo.md +35 -0
- package/templates/default/content/slides/docs/code-demo.md +62 -0
- package/templates/default/content/slides/docs/echarts-demo.md +139 -0
- package/templates/default/content/slides/docs/fragment-demo.md +35 -0
- package/templates/default/content/slides/docs/math-demo.md +48 -0
- package/templates/default/content/slides/docs/mermaid-demo.md +105 -0
- package/templates/default/content/slides/docs/theme-demo.md +38 -0
- package/templates/default/content/slides/docs/vertical-demo.md +50 -0
- package/templates/default/package.json +31 -0
- package/templates/default/public/favicon-bak.svg +4 -0
- package/templates/default/public/images/avatar.jpg +0 -0
- package/templates/default/public/images/avatar.svg +142 -0
- package/templates/default/public/js/mermaid-container.js +402 -0
- package/templates/default/public/js/mermaid-init.js +131 -0
- package/templates/default/public/js/mermaid-render.js +98 -0
- package/templates/default/public/js/mermaid-simple.js +95 -0
- package/templates/default/public/js/tabs-init.js +86 -0
- package/templates/default/public/media/individual_portfolio/INDIVIDUAL PORTFOLIO.png +0 -0
- package/templates/default/public/slides/plugin/highlight/highlight.js +5 -0
- package/templates/default/public/slides/plugin/highlight/monokai.css +71 -0
- package/templates/default/public/slides/plugin/markdown/markdown.js +7 -0
- package/templates/default/public/slides/plugin/math/math.js +1 -0
- package/templates/default/public/slides/plugin/notes/notes.js +1 -0
- package/templates/default/public/slides/reveal.css +9 -0
- package/templates/default/public/slides/reveal.js +9 -0
- package/templates/default/public/slides/theme/beige.css +366 -0
- package/templates/default/public/slides/theme/black-contrast.css +362 -0
- package/templates/default/public/slides/theme/black.css +359 -0
- package/templates/default/public/slides/theme/blood.css +392 -0
- package/templates/default/public/slides/theme/dracula.css +385 -0
- package/templates/default/public/slides/theme/league.css +368 -0
- package/templates/default/public/slides/theme/moon.css +362 -0
- package/templates/default/public/slides/theme/night.css +360 -0
- package/templates/default/public/slides/theme/serif.css +363 -0
- package/templates/default/public/slides/theme/simple.css +362 -0
- package/templates/default/public/slides/theme/sky.css +370 -0
- package/templates/default/public/slides/theme/solarized.css +363 -0
- package/templates/default/public/slides/theme/white-contrast.css +362 -0
- package/templates/default/public/slides/theme/white.css +359 -0
- package/templates/default/public/slides/theme/white_contrast_compact_verbatim_headers.css +360 -0
- package/templates/default/public/test-complete.html +43 -0
- package/templates/default/public/test-mermaid.html +124 -0
- package/templates/default/src/config/index.ts +114 -0
- package/templates/default/src/content.config.ts +96 -0
- package/templates/default/src/pages/[...slug].astro +27 -0
- package/templates/default/src/pages/archives/[year]/[month]/page/[page].astro +176 -0
- package/templates/default/src/pages/archives/[year]/[month].astro +158 -0
- package/templates/default/src/pages/archives/index.astro +210 -0
- package/templates/default/src/pages/categories/[category]/page/[page].astro +218 -0
- package/templates/default/src/pages/categories/[category].astro +198 -0
- package/templates/default/src/pages/categories/index.astro +190 -0
- package/templates/default/src/pages/container-test.astro +79 -0
- package/templates/default/src/pages/mermaid-direct.html +78 -0
- package/templates/default/src/pages/posts/[...slug].astro +335 -0
- package/templates/default/src/pages/posts/index.astro +541 -0
- package/templates/default/src/pages/posts/page/[page].astro +146 -0
- package/templates/default/src/pages/rss.xml.ts +28 -0
- package/templates/default/src/pages/search-index.json.ts +21 -0
- package/templates/default/src/pages/search.astro +50 -0
- package/templates/default/src/pages/slides/[...slug].astro +54 -0
- package/templates/default/src/pages/slides/index.astro +135 -0
- package/templates/default/src/pages/tags/[tag]/page/[page].astro +211 -0
- package/templates/default/src/pages/tags/[tag].astro +191 -0
- package/templates/default/src/pages/tags/index.astro +167 -0
- package/templates/default/tailwind.config.mjs +78 -0
- package/templates/default/tsconfig.json +9 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 代码块与高亮
|
|
3
|
+
description: 代码展示的最佳实践和高级用法
|
|
4
|
+
pubDate: 2025-12-11
|
|
5
|
+
author: Astro Blog
|
|
6
|
+
categories:
|
|
7
|
+
- 博客教程
|
|
8
|
+
tags:
|
|
9
|
+
- 代码
|
|
10
|
+
- 语法高亮
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# 代码块与高亮
|
|
14
|
+
|
|
15
|
+
本博客使用 Shiki 进行代码语法高亮,支持 100+ 编程语言,并提供代码复制、折叠等增强功能。
|
|
16
|
+
|
|
17
|
+
## 基本用法
|
|
18
|
+
|
|
19
|
+
### 行内代码
|
|
20
|
+
|
|
21
|
+
使用单个反引号包裹:
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
使用 `npm install` 安装依赖。
|
|
25
|
+
变量 `count` 的值为 `10`。
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
效果:使用 `npm install` 安装依赖。
|
|
29
|
+
|
|
30
|
+
### 代码块
|
|
31
|
+
|
|
32
|
+
使用三个反引号包裹,并指定语言:
|
|
33
|
+
|
|
34
|
+
````markdown
|
|
35
|
+
```javascript
|
|
36
|
+
function hello(name) {
|
|
37
|
+
console.log(`Hello, ${name}!`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
hello('World');
|
|
41
|
+
```
|
|
42
|
+
````
|
|
43
|
+
|
|
44
|
+
效果:
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
function hello(name) {
|
|
48
|
+
console.log(`Hello, ${name}!`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
hello('World');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 支持的语言
|
|
55
|
+
|
|
56
|
+
博客支持众多编程语言,常用的包括:
|
|
57
|
+
|
|
58
|
+
| 语言 | 标识符 | 语言 | 标识符 |
|
|
59
|
+
|:---|:---|:---|:---|
|
|
60
|
+
| JavaScript | `javascript` 或 `js` | Python | `python` 或 `py` |
|
|
61
|
+
| TypeScript | `typescript` 或 `ts` | Java | `java` |
|
|
62
|
+
| HTML | `html` | CSS | `css` |
|
|
63
|
+
| Vue | `vue` | React JSX | `jsx` |
|
|
64
|
+
| Bash | `bash` 或 `shell` | SQL | `sql` |
|
|
65
|
+
| JSON | `json` | YAML | `yaml` |
|
|
66
|
+
| Markdown | `markdown` 或 `md` | Go | `go` |
|
|
67
|
+
| Rust | `rust` | C/C++ | `c` / `cpp` |
|
|
68
|
+
|
|
69
|
+
## 语言示例
|
|
70
|
+
|
|
71
|
+
### JavaScript / TypeScript
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// ES6+ 特性
|
|
75
|
+
const greet = (name) => `Hello, ${name}!`;
|
|
76
|
+
|
|
77
|
+
async function fetchData(url) {
|
|
78
|
+
const response = await fetch(url);
|
|
79
|
+
return response.json();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 解构赋值
|
|
83
|
+
const { name, age } = user;
|
|
84
|
+
const [first, ...rest] = array;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
interface User {
|
|
89
|
+
id: number;
|
|
90
|
+
name: string;
|
|
91
|
+
email?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getUser(id: number): Promise<User> {
|
|
95
|
+
return fetch(`/api/users/${id}`).then(res => res.json());
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Vue
|
|
100
|
+
|
|
101
|
+
```vue
|
|
102
|
+
<template>
|
|
103
|
+
<div class="counter">
|
|
104
|
+
<button @click="decrement">-</button>
|
|
105
|
+
<span>{{ count }}</span>
|
|
106
|
+
<button @click="increment">+</button>
|
|
107
|
+
</div>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<script setup lang="ts">
|
|
111
|
+
import { ref } from 'vue';
|
|
112
|
+
|
|
113
|
+
const count = ref(0);
|
|
114
|
+
const increment = () => count.value++;
|
|
115
|
+
const decrement = () => count.value--;
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<style scoped>
|
|
119
|
+
.counter {
|
|
120
|
+
display: flex;
|
|
121
|
+
gap: 1rem;
|
|
122
|
+
}
|
|
123
|
+
</style>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Python
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from typing import List, Optional
|
|
130
|
+
|
|
131
|
+
class DataProcessor:
|
|
132
|
+
def __init__(self, data: List[dict]):
|
|
133
|
+
self.data = data
|
|
134
|
+
|
|
135
|
+
def filter_by(self, key: str, value: any) -> List[dict]:
|
|
136
|
+
"""根据键值对过滤数据"""
|
|
137
|
+
return [item for item in self.data if item.get(key) == value]
|
|
138
|
+
|
|
139
|
+
async def fetch_and_process(self, url: str) -> Optional[dict]:
|
|
140
|
+
async with aiohttp.ClientSession() as session:
|
|
141
|
+
async with session.get(url) as response:
|
|
142
|
+
return await response.json()
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Bash / Shell
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
#!/bin/bash
|
|
149
|
+
|
|
150
|
+
# 变量定义
|
|
151
|
+
PROJECT_NAME="my-project"
|
|
152
|
+
BUILD_DIR="./dist"
|
|
153
|
+
|
|
154
|
+
# 函数定义
|
|
155
|
+
build() {
|
|
156
|
+
echo "Building $PROJECT_NAME..."
|
|
157
|
+
npm run build
|
|
158
|
+
|
|
159
|
+
if [ $? -eq 0 ]; then
|
|
160
|
+
echo "Build successful!"
|
|
161
|
+
else
|
|
162
|
+
echo "Build failed!" >&2
|
|
163
|
+
exit 1
|
|
164
|
+
fi
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# 执行构建
|
|
168
|
+
build
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### SQL
|
|
172
|
+
|
|
173
|
+
```sql
|
|
174
|
+
-- 创建用户表
|
|
175
|
+
CREATE TABLE users (
|
|
176
|
+
id SERIAL PRIMARY KEY,
|
|
177
|
+
username VARCHAR(50) NOT NULL UNIQUE,
|
|
178
|
+
email VARCHAR(100) NOT NULL,
|
|
179
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
-- 查询活跃用户
|
|
183
|
+
SELECT
|
|
184
|
+
u.username,
|
|
185
|
+
COUNT(p.id) AS post_count
|
|
186
|
+
FROM users u
|
|
187
|
+
LEFT JOIN posts p ON u.id = p.author_id
|
|
188
|
+
WHERE u.created_at > '2024-01-01'
|
|
189
|
+
GROUP BY u.id
|
|
190
|
+
HAVING COUNT(p.id) > 5
|
|
191
|
+
ORDER BY post_count DESC;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### JSON / YAML
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"name": "my-project",
|
|
199
|
+
"version": "1.0.0",
|
|
200
|
+
"dependencies": {
|
|
201
|
+
"vue": "^3.4.0",
|
|
202
|
+
"axios": "^1.6.0"
|
|
203
|
+
},
|
|
204
|
+
"scripts": {
|
|
205
|
+
"dev": "vite",
|
|
206
|
+
"build": "vite build"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
# docker-compose.yml
|
|
213
|
+
version: '3.8'
|
|
214
|
+
|
|
215
|
+
services:
|
|
216
|
+
web:
|
|
217
|
+
build: .
|
|
218
|
+
ports:
|
|
219
|
+
- "3000:3000"
|
|
220
|
+
environment:
|
|
221
|
+
- NODE_ENV=production
|
|
222
|
+
depends_on:
|
|
223
|
+
- db
|
|
224
|
+
|
|
225
|
+
db:
|
|
226
|
+
image: postgres:15
|
|
227
|
+
volumes:
|
|
228
|
+
- pgdata:/var/lib/postgresql/data
|
|
229
|
+
environment:
|
|
230
|
+
POSTGRES_PASSWORD: secret
|
|
231
|
+
|
|
232
|
+
volumes:
|
|
233
|
+
pgdata:
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## 代码块功能
|
|
237
|
+
|
|
238
|
+
### 自动语言检测
|
|
239
|
+
|
|
240
|
+
代码块顶部会显示语言标识:
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
print("This shows 'python' label")
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 代码复制
|
|
247
|
+
|
|
248
|
+
每个代码块右上角有复制按钮,点击即可复制代码。
|
|
249
|
+
|
|
250
|
+
### 代码折叠
|
|
251
|
+
|
|
252
|
+
超过 15 行的代码块会自动折叠,点击"展开代码"查看完整内容:
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
// 这是一个较长的代码示例
|
|
256
|
+
// 用于演示代码折叠功能
|
|
257
|
+
|
|
258
|
+
class EventEmitter {
|
|
259
|
+
constructor() {
|
|
260
|
+
this.events = {};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
on(event, listener) {
|
|
264
|
+
if (!this.events[event]) {
|
|
265
|
+
this.events[event] = [];
|
|
266
|
+
}
|
|
267
|
+
this.events[event].push(listener);
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
off(event, listener) {
|
|
272
|
+
if (!this.events[event]) return this;
|
|
273
|
+
this.events[event] = this.events[event].filter(l => l !== listener);
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
emit(event, ...args) {
|
|
278
|
+
if (!this.events[event]) return false;
|
|
279
|
+
this.events[event].forEach(listener => listener.apply(this, args));
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
once(event, listener) {
|
|
284
|
+
const onceListener = (...args) => {
|
|
285
|
+
listener.apply(this, args);
|
|
286
|
+
this.off(event, onceListener);
|
|
287
|
+
};
|
|
288
|
+
return this.on(event, onceListener);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// 使用示例
|
|
293
|
+
const emitter = new EventEmitter();
|
|
294
|
+
emitter.on('data', (data) => console.log(data));
|
|
295
|
+
emitter.emit('data', { message: 'Hello!' });
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## 无语言代码块
|
|
299
|
+
|
|
300
|
+
如果不指定语言,代码块会显示为纯文本:
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
这是纯文本代码块
|
|
304
|
+
不会进行语法高亮
|
|
305
|
+
适合显示命令输出等
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
指定 `text` 或 `plaintext` 也可以:
|
|
309
|
+
|
|
310
|
+
```text
|
|
311
|
+
[INFO] 2024-01-01 10:00:00 - Application started
|
|
312
|
+
[DEBUG] 2024-01-01 10:00:01 - Loading configuration...
|
|
313
|
+
[INFO] 2024-01-01 10:00:02 - Ready to accept connections
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## 最佳实践
|
|
317
|
+
|
|
318
|
+
### 1. 始终指定语言
|
|
319
|
+
|
|
320
|
+
```markdown
|
|
321
|
+
<!-- 好 -->
|
|
322
|
+
```javascript
|
|
323
|
+
const x = 1;
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
<!-- 不好 -->
|
|
327
|
+
```
|
|
328
|
+
const x = 1;
|
|
329
|
+
```
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### 2. 保持代码简洁
|
|
333
|
+
|
|
334
|
+
```markdown
|
|
335
|
+
<!-- 好:只展示关键代码 -->
|
|
336
|
+
```javascript
|
|
337
|
+
// 关键实现
|
|
338
|
+
const result = data.filter(x => x.active).map(x => x.name);
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
<!-- 不好:包含过多无关代码 -->
|
|
342
|
+
```javascript
|
|
343
|
+
// 导入模块
|
|
344
|
+
import { something } from 'somewhere';
|
|
345
|
+
import { another } from 'another-place';
|
|
346
|
+
// ... 很多无关代码 ...
|
|
347
|
+
const result = data.filter(x => x.active).map(x => x.name);
|
|
348
|
+
// ... 更多无关代码 ...
|
|
349
|
+
```
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### 3. 添加必要注释
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
// 使用 reduce 计算总和
|
|
356
|
+
const total = numbers.reduce((sum, num) => sum + num, 0);
|
|
357
|
+
|
|
358
|
+
// 解构并设置默认值
|
|
359
|
+
const { name = 'Anonymous', age = 0 } = user;
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 4. 使用正确的语言标识
|
|
363
|
+
|
|
364
|
+
```markdown
|
|
365
|
+
<!-- Vue 单文件组件用 vue -->
|
|
366
|
+
```vue
|
|
367
|
+
<template>...</template>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
<!-- React JSX 用 jsx 或 tsx -->
|
|
371
|
+
```jsx
|
|
372
|
+
function App() {
|
|
373
|
+
return <div>Hello</div>;
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
<!-- 命令行用 bash -->
|
|
378
|
+
```bash
|
|
379
|
+
npm install package-name
|
|
380
|
+
```
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## 下一步
|
|
384
|
+
|
|
385
|
+
学习更多可视化功能:
|
|
386
|
+
|
|
387
|
+
- [Mermaid 图表](./06-mermaid) - 绘制流程图、时序图等
|
|
388
|
+
- [LaTeX 数学公式](./07-latex) - 数学公式排版
|