关于 slidev-monaco-editor
slidev-monaco-editor 是面向 Slidev 演示文稿作者的技能,讲解如何将 Monaco Editor 用于现场编码和交互式代码演示。它涵盖可编辑代码块、运行代码、输出显示及编辑器配置。
主要功能
- 01可编辑的 Monaco 代码块
- 02JavaScript 与 TypeScript 代码运行
- 03显示运行输出
- 04只读与差异编辑器模式
- 05配置编辑器选项与主题
适用场景
- 01现场演示代码编辑
- 02运行示例并查看输出
- 03讲授编程概念
- 04制作可交互的代码练习
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yoanbernabeu/ slidev-skills --skill slidev-monaco-editor安装后在 Claude Code 中输入/slidev-monaco-editor确认已加载。
详细介绍
Slidev 中的 Monaco Editor
本技能介绍如何在 Slidev 演示文稿中集成 Monaco Editor(VS Code 使用的编辑器),以实现实时编码、交互式演示和可执行代码块。
何时使用此技能
- 实时编码演示
- 演示期间交互式编辑代码
- 实时运行代码示例
- 教授编程概念
- 展示自动补全和类型提示
启用 Monaco Editor
基础 Monaco 代码块
在任意代码块中添加 {monaco}:
```typescript {monaco}
const greeting = 'Hello, World!'
console.log(greeting)
```
这会创建一个可编辑代码块,支持:
- 语法高亮
- 自动补全
- 类型检查(适用于 TypeScript)
- 括号匹配
带行高亮的 Monaco
```typescript {monaco}{2,3}
const a = 1
const b = 2 // highlighted
const c = 3 // highlighted
```
Monaco 运行器
在演示文稿中直接执行代码:
JavaScript 运行器
```javascript {monaco-run}
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled)
```
点击“Run”即可执行并查看输出。
TypeScript 运行器
```typescript {monaco-run}
interface User {
name: string
age: number
}
const user: User = {
name: 'John',
age: 30
}
console.log(`${user.name} is ${user.age} years old`)
```
加载时自动运行
```javascript {monaco-run} {autorun:true}
console.log('This runs automatically!')
```
仅显示输出
```javascript {monaco-run} {showOutputAt:'+1'}
// Output shows after one click
console.log('Hello!')
```
配置选项
编辑器高度
```typescript {monaco}{height:'300px'}
// Taller editor
function longFunction() {
// ...
}
```
只读模式
```typescript {monaco}{readonly:true}
// Cannot be edited
const CONSTANT = 'value'
```
差异编辑器
```typescript {monaco-diff}
const original = 'Hello'
~~~
const modified = 'Hello, World!'
```
Monaco 设置配置
setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'
export default defineMonacoSetup((monaco) => {
// Editor options
return {
editorOptions: {
fontSize: 14,
fontFamily: 'JetBrains Mono, monospace',
minimap: { enabled: false },
lineNumbers: 'on',
wordWrap: 'on',
tabSize: 2,
scrollBeyondLastLine: false,
automaticLayout: true,
},
// Light/dark theme
theme: {
light: 'vs',
dark: 'vs-dark',
},
}
})
自定义主题
import { defineMonacoSetup } from '@slidev/types'
export default defineMonacoSetup((monaco) => {
// Define custom theme
monaco.editor.defineTheme('my-theme', {
base: 'vs-dark',
inherit: true,
rules: [
{ token: 'comment', foreground: '6A9955' },
{ token: 'keyword', foreground: 'C586C0' },
],
colors: {
'editor.background': '#1a1a2e',
},
})
return {
theme: {
dark: 'my-theme',
light: 'vs',
},
}
})
类型定义
为库添加类型
// setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'
export default defineMonacoSetup(async (monaco) => {
// Add React types
const reactTypes = await fetch(
'https://unpkg.com/@types/react/index.d.ts'
).then(r => r.text())
monaco.languages.typescript.typescriptDefaults.addExtraLib(
reactTypes,
'file:///node_modules/@types/react/index.d.ts'
)
})
内联类型定义
```typescript {monaco}
// Types defined inline
interface Todo {
id: number
text: string
completed: boolean
}
const todos: Todo[] = [
{ id: 1, text: 'Learn Slidev', completed: true },
{ id: 2, text: 'Create presentation', completed: false },
]
```
交互式示例
计数器演示
```typescript {monaco-run}
// Interactive counter
let count = 0
function increment() {
count++
console.log(`Count: ${count}`)
}
// Click Run multiple times!
increment()
```
API 模拟
```typescript {monaco-run}
// Simulated API call
async function fetchUser(id: number) {
// Simulate network delay
await new Promise(r => setTimeout(r, 500))
return {
id,
name: 'John Doe',
email: '[email protected]'
}
}
const user = await fetchUser(1)
console.log(user)
```
算法可视化
```typescript {monaco-run}
// Bubble sort with steps
function bubbleSort(arr: number[]) {
const result = [...arr]
const steps: string[] = []
for (let i = 0; i < result.length; i++) {
for (let j = 0; j < result.length - i - 1; j++) {
if (result[j] > result[j + 1]) {
[result[j], result[j + 1]] = [result[j + 1], result[j]]
steps.push(`Swap: [${result.join(', ')}]`)
}
}
}
return { result, steps }
}
const { result, steps } = bubbleSort([5, 3, 8, 4, 2])
console.log('Steps:', steps.length)
steps.forEach(s => console.log(s))
console.log('Final:', result)
```
代码运行器模式
先展示概念,再让用户编辑
# Array Methods
```typescript {monaco-run}
const numbers = [1, 2, 3, 4, 5]
// Try changing the function!
const result = numbers
.filter(n => n % 2 === 0)
.map(n => n * 2)
console.log(result)
```
Try modifying the code to:
- Filter odd numbers
- Triple instead of double
交互式测验
# Fix the Bug
```typescript {monaco-run}
// This code has a bug - can you fix it?
function reverseString(str: string) {
return str.split('').reserve().join('')
}
console.log(reverseString('hello'))
// Expected: 'olleh'
```
实时数据处理
```typescript {monaco-run}
const data = [
{ name: 'Alice', score: 85 },
{ name: 'Bob', score: 92 },
{ name: 'Charlie', score: 78 },
]
// Calculate statistics
const average = data.reduce((sum, d) => sum + d.score, 0) / data.length
const highest = Math.max(...data.map(d => d.score))
const passing = data.filter(d => d.score >= 80)
console.log(`Average: ${average.toFixed(1)}`)
console.log(`Highest: ${highest}`)
console.log(`Passing: ${passing.map(d => d.name).join(', ')}`)
```
与动画结合
先揭示,再编辑
<v-click>
```typescript {monaco}
// Code appears on click, then is editable
function greet(name: string) {
return `Hello, ${name}!`
}
```
</v-click>
使用 Monaco 分步展示
<v-clicks>
Start with this code:
```typescript {monaco}
const x = 1
```
Then try adding more lines!
</v-clicks>
最佳实践
1. 聚焦示例内容
```typescript {monaco-run}
// GOOD: Single concept
const sum = [1, 2, 3].reduce((a, b) => a + b, 0)
console.log(sum) // 6
```
2. 提供起点
```typescript {monaco-run}
// Complete the function:
function capitalize(str: string): string {
// Your code here
return str
}
console.log(capitalize('hello')) // Should print: 'Hello'
```
3. 显示预期输出
```typescript {monaco-run}
// Code example
const result = [1, 2, 3].map(n => n ** 2)
console.log(result)
// Expected output: [1, 4, 9]
```
4. 妥善处理错误
```typescript {monaco-run}
try {
const result = riskyOperation()
console.log(result)
} catch (error) {
console.error('Error:', error.message)
}
function riskyOperation() {
// Might throw an error
throw new Error('Oops!')
}
```
限制
- 无法访问 DOM:不能操作页面 DOM
- API 有限:仅提供标准 JavaScript API
- 不支持导入:无法导入外部包
- 仅支持控制台输出:输出基于控制台
输出格式
创建 Monaco 代码块时:
PURPOSE: [What the code demonstrates]
INTERACTION: [How audience should interact]
CODE:
```[language] {monaco-run}
// Clear comments explaining purpose
[Code with good defaults]
// Expected output noted
建议修改:
- 尝试将 X 改为 Y
- 修改函数以实现 Z
评论
支持 Markdown