@tuoyuan/code-editor 1.0.0 → 1.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/README.md +424 -357
- package/dist/JavascriptEditor.vue.d.ts +319 -0
- package/dist/JsonEditor.vue.d.ts +322 -0
- package/dist/SqlEditor.vue.d.ts +319 -0
- package/dist/{cssMode-BfZeZ0sl.js → cssMode-BpY2QZKm.js} +1 -1
- package/dist/{cssMode-CroponXs.cjs → cssMode-Opz_JLpw.cjs} +1 -1
- package/dist/{freemarker2-CpMdvAfd.cjs → freemarker2-B09dYp00.cjs} +1 -1
- package/dist/{freemarker2-DVRVJu0B.js → freemarker2-uBVO2rOF.js} +1 -1
- package/dist/{handlebars-8AMUT0_r.cjs → handlebars-DA1mbfg8.cjs} +1 -1
- package/dist/{handlebars-cspegSxe.js → handlebars-DCXZu403.js} +1 -1
- package/dist/{html-zabMn0fr.js → html-DaWChHgh.js} +1 -1
- package/dist/{html-Bvlf1Z20.cjs → html-DqYDmf6m.cjs} +1 -1
- package/dist/{htmlMode-jXZ-OnTX.js → htmlMode-BmaRbaUb.js} +1 -1
- package/dist/{htmlMode-B3y58LIC.cjs → htmlMode-OnZuz9_d.cjs} +1 -1
- package/dist/{index-BvnET_j2.js → index-CGIln256.js} +18264 -17748
- package/dist/{index-CjGIE44E.cjs → index-CkYrsRHd.cjs} +198 -194
- package/dist/index.d.ts +6 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +6 -3
- package/dist/{javascript-QgWqIxzo.cjs → javascript-CZ5LkNUz.cjs} +1 -1
- package/dist/{javascript-BF91TgD3.js → javascript-kyQzET-h.js} +1 -1
- package/dist/{jsonMode-Chpjh-RM.cjs → jsonMode-BjlrCQBF.cjs} +1 -1
- package/dist/{jsonMode-DD3uMliY.js → jsonMode-DkgDlnQP.js} +1 -1
- package/dist/{liquid-CsQKIvsE.cjs → liquid-BV_g9ldr.cjs} +1 -1
- package/dist/{liquid-DxypC1q6.js → liquid-DBmQt-Su.js} +1 -1
- package/dist/{mdx-DZRrNJcb.js → mdx-CMn_WqRG.js} +1 -1
- package/dist/{mdx-BvsKvd6j.cjs → mdx-CnlGeQWI.cjs} +1 -1
- package/dist/{python-CXOcTmBp.js → python-CIMw6KAi.js} +1 -1
- package/dist/{python-CDI0D2Kf.cjs → python-jV8ElUmA.cjs} +1 -1
- package/dist/{razor-CAIWGDkN.cjs → razor-B0mOsBYm.cjs} +1 -1
- package/dist/{razor-Do5Lpn1p.js → razor-BMsZkT51.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/{tsMode-D7bHvHeH.cjs → tsMode-CVcmC_63.cjs} +1 -1
- package/dist/{tsMode-DiYbk3vf.js → tsMode-m-l3aETM.js} +1 -1
- package/dist/types.d.ts +28 -0
- package/dist/{typescript-DFdjl8Xj.js → typescript-DEwfjYff.js} +1 -1
- package/dist/{typescript-CI6w3N2S.cjs → typescript-I5zQzQ1C.cjs} +1 -1
- package/dist/{xml-CJndgX4z.js → xml-43tWDt_9.js} +1 -1
- package/dist/{xml-CO5xAOVk.cjs → xml-BGfSJ1L-.cjs} +1 -1
- package/dist/{yaml-BYk2IWKs.cjs → yaml-B1huN312.cjs} +1 -1
- package/dist/{yaml--krIkoJ8.js → yaml-CdouwYEZ.js} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,178 +1,176 @@
|
|
|
1
1
|
# @tuoyuan/code-editor
|
|
2
2
|
|
|
3
|
-
基于 Monaco Editor 的
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- 🎨
|
|
8
|
-
- 🌈
|
|
9
|
-
- 📝
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- 📊 **状态栏**:显示光标位置、行数、字符数等统计信息
|
|
15
|
-
- 📋 **复制代码**:一键复制编辑器内容
|
|
16
|
-
- 💿 **下载代码**:导出为文件
|
|
17
|
-
- 🖥️ **全屏模式**:支持全屏编辑,ESC 退出
|
|
18
|
-
- 🔧 **零配置**:内置 Worker 配置,无需额外设置
|
|
19
|
-
- 📦 **轻量级封装**:参考了 devops-platform 和 dashboard-manage.web 的最佳实践
|
|
3
|
+
基于 Monaco Editor 的 Vue 3 代码编辑器组件库,提供三个独立的语言编辑器组件。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🎨 基于 Monaco Editor(VS Code 编辑器核心)
|
|
8
|
+
- 🌈 支持三种主题:浅色、深色、高对比度
|
|
9
|
+
- 📝 三个独立编辑器:JavascriptEditor、JsonEditor、SqlEditor
|
|
10
|
+
- ✨ 代码格式化和压缩功能
|
|
11
|
+
- 🔧 完全可定制的编辑器选项
|
|
12
|
+
- 📦 开箱即用,无需额外配置
|
|
13
|
+
- 💪 完整的 TypeScript 支持
|
|
20
14
|
|
|
21
15
|
## 安装
|
|
22
16
|
|
|
23
17
|
```bash
|
|
24
|
-
npm install @tuoyuan/code-editor
|
|
25
|
-
# or
|
|
26
|
-
pnpm add @tuoyuan/code-editor monaco-editor
|
|
27
|
-
# or
|
|
28
|
-
yarn add @tuoyuan/code-editor monaco-editor
|
|
18
|
+
npm install @tuoyuan/code-editor
|
|
29
19
|
```
|
|
30
20
|
|
|
31
|
-
##
|
|
21
|
+
## 组件介绍
|
|
22
|
+
|
|
23
|
+
本组件库提供三个完全独立的编辑器组件,每个组件专注于一种编程语言:
|
|
32
24
|
|
|
33
|
-
|
|
25
|
+
- **JavascriptEditor** - JavaScript 代码编辑器
|
|
26
|
+
- **JsonEditor** - JSON 数据编辑器(带验证功能)
|
|
27
|
+
- **SqlEditor** - SQL 查询编辑器
|
|
28
|
+
|
|
29
|
+
## 快速开始
|
|
30
|
+
|
|
31
|
+
### JavaScript 编辑器
|
|
34
32
|
|
|
35
33
|
```vue
|
|
36
34
|
<template>
|
|
37
|
-
<
|
|
38
|
-
v-model="code"
|
|
39
|
-
language="javascript"
|
|
40
|
-
height="400px"
|
|
41
|
-
/>
|
|
35
|
+
<JavascriptEditor v-model="jsCode" height="500px" />
|
|
42
36
|
</template>
|
|
43
37
|
|
|
44
|
-
<script setup
|
|
38
|
+
<script setup>
|
|
45
39
|
import { ref } from 'vue'
|
|
46
|
-
import {
|
|
40
|
+
import { JavascriptEditor } from '@tuoyuan/code-editor'
|
|
47
41
|
import '@tuoyuan/code-editor/dist/style.css'
|
|
48
42
|
|
|
49
|
-
const
|
|
43
|
+
const jsCode = ref('console.log("Hello World")')
|
|
50
44
|
</script>
|
|
51
45
|
```
|
|
52
46
|
|
|
53
|
-
###
|
|
47
|
+
### JSON 编辑器
|
|
54
48
|
|
|
55
49
|
```vue
|
|
56
50
|
<template>
|
|
57
|
-
<
|
|
58
|
-
<!-- 外部操作按钮 -->
|
|
59
|
-
<div style="margin-bottom: 10px;">
|
|
60
|
-
<button @click="copyCode">复制代码</button>
|
|
61
|
-
<button @click="downloadCode">下载代码</button>
|
|
62
|
-
<button @click="toggleFullscreen">全屏</button>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<!-- 代码编辑器 -->
|
|
66
|
-
<CodeEditor
|
|
67
|
-
ref="editorRef"
|
|
68
|
-
v-model="code"
|
|
69
|
-
v-model:language="language"
|
|
70
|
-
v-model:theme="theme"
|
|
71
|
-
height="500px"
|
|
72
|
-
:show-toolbar="true"
|
|
73
|
-
@change="onChange"
|
|
74
|
-
@save="onSave"
|
|
75
|
-
@format="onFormat"
|
|
76
|
-
@minify="onMinify"
|
|
77
|
-
@copy="onCopy"
|
|
78
|
-
@download="onDownload"
|
|
79
|
-
@fullscreen="onFullscreenChange"
|
|
80
|
-
/>
|
|
81
|
-
</div>
|
|
51
|
+
<JsonEditor v-model="jsonCode" height="500px" />
|
|
82
52
|
</template>
|
|
83
53
|
|
|
84
|
-
<script setup
|
|
54
|
+
<script setup>
|
|
85
55
|
import { ref } from 'vue'
|
|
86
|
-
import {
|
|
87
|
-
import type { CodeEditorInstance } from '@tuoyuan/code-editor'
|
|
56
|
+
import { JsonEditor } from '@tuoyuan/code-editor'
|
|
88
57
|
import '@tuoyuan/code-editor/dist/style.css'
|
|
89
58
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const theme = ref<'vs' | 'vs-dark' | 'hc-black'>('vs')
|
|
94
|
-
|
|
95
|
-
// 复制代码
|
|
96
|
-
const copyCode = async () => {
|
|
97
|
-
const success = await editorRef.value?.copyCode()
|
|
98
|
-
if (success) {
|
|
99
|
-
alert('代码已复制')
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// 下载代码
|
|
104
|
-
const downloadCode = () => {
|
|
105
|
-
editorRef.value?.downloadCode('my-code.js')
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// 切换全屏
|
|
109
|
-
const toggleFullscreen = () => {
|
|
110
|
-
editorRef.value?.toggleFullscreen()
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// 事件处理
|
|
114
|
-
const onChange = (value: string) => {
|
|
115
|
-
console.log('代码变化:', value)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const onSave = (value: string) => {
|
|
119
|
-
console.log('保存代码:', value)
|
|
120
|
-
// 在这里处理保存逻辑,如保存到服务器
|
|
121
|
-
}
|
|
59
|
+
const jsonCode = ref('{"name": "example"}')
|
|
60
|
+
</script>
|
|
61
|
+
```
|
|
122
62
|
|
|
123
|
-
|
|
124
|
-
console.log('格式化完成')
|
|
125
|
-
}
|
|
63
|
+
### SQL 编辑器
|
|
126
64
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const onCopy = (value: string) => {
|
|
132
|
-
console.log('代码已复制')
|
|
133
|
-
}
|
|
65
|
+
```vue
|
|
66
|
+
<template>
|
|
67
|
+
<SqlEditor v-model="sqlCode" height="500px" />
|
|
68
|
+
</template>
|
|
134
69
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
70
|
+
<script setup>
|
|
71
|
+
import { ref } from 'vue'
|
|
72
|
+
import { SqlEditor } from '@tuoyuan/code-editor'
|
|
73
|
+
import '@tuoyuan/code-editor/dist/style.css'
|
|
138
74
|
|
|
139
|
-
const
|
|
140
|
-
console.log('全屏状态:', isFullscreen)
|
|
141
|
-
}
|
|
75
|
+
const sqlCode = ref('SELECT * FROM users')
|
|
142
76
|
</script>
|
|
143
77
|
```
|
|
144
78
|
|
|
145
|
-
|
|
79
|
+
## API 文档
|
|
80
|
+
|
|
81
|
+
### 通用 Props(所有编辑器组件都支持)
|
|
82
|
+
|
|
83
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
84
|
+
|------|------|--------|------|
|
|
85
|
+
| `modelValue` | `string` | `''` | 编辑器内容(v-model) |
|
|
86
|
+
| `theme` | `'vs' \| 'vs-dark' \| 'hc-black'` | `'vs-dark'` | 编辑器主题(浅色/暗黑/高对比度) |
|
|
87
|
+
| `height` | `string` | `'400px'` | 编辑器高度 |
|
|
88
|
+
| `readonly` | `boolean` | `false` | 是否只读 |
|
|
89
|
+
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
|
90
|
+
| `options` | `editor.IStandaloneEditorConstructionOptions` | `{}` | Monaco Editor 原生配置 |
|
|
91
|
+
|
|
92
|
+
### 通用 Events(所有编辑器组件都支持)
|
|
93
|
+
|
|
94
|
+
| 事件名 | 参数 | 说明 |
|
|
95
|
+
|--------|------|------|
|
|
96
|
+
| `update:modelValue` | `(value: string)` | 内容变化时触发 |
|
|
97
|
+
| `change` | `(value: string)` | 内容变化时触发 |
|
|
98
|
+
| `blur` | `(value: string)` | 失去焦点时触发 |
|
|
99
|
+
| `format` | `(value: string)` | 格式化代码后触发 |
|
|
100
|
+
| `minify` | `(value: string)` | 压缩代码后触发 |
|
|
101
|
+
| `save` | `(value: string)` | 保存代码时触发(Ctrl+S) |
|
|
102
|
+
|
|
103
|
+
### JavascriptEditor 专属方法
|
|
104
|
+
|
|
105
|
+
通过模板引用可以访问以下方法:
|
|
106
|
+
|
|
107
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
108
|
+
|--------|------|--------|------|
|
|
109
|
+
| `formatJavascript()` | - | `void` | 格式化 JavaScript 代码 |
|
|
110
|
+
| `minifyJavascript()` | - | `void` | 压缩 JavaScript 代码 |
|
|
111
|
+
| `saveJavascript()` | - | `void` | 触发保存事件 |
|
|
112
|
+
| `getValue()` | - | `string` | 获取编辑器内容 |
|
|
113
|
+
| `setValue(value)` | `value: string` | `void` | 设置编辑器内容 |
|
|
114
|
+
| `refresh()` | - | `void` | 刷新编辑器布局 |
|
|
115
|
+
| `editor` | - | `IStandaloneCodeEditor` | Monaco Editor 实例 |
|
|
116
|
+
|
|
117
|
+
### JsonEditor 专属方法
|
|
118
|
+
|
|
119
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
120
|
+
|--------|------|--------|------|
|
|
121
|
+
| `formatJson()` | - | `void` | 格式化 JSON 代码 |
|
|
122
|
+
| `minifyJson()` | - | `void` | 压缩 JSON 代码 |
|
|
123
|
+
| `validateJson()` | - | `boolean` | 验证 JSON 格式 |
|
|
124
|
+
| `saveJson()` | - | `void` | 触发保存事件 |
|
|
125
|
+
| `getValue()` | - | `string` | 获取编辑器内容 |
|
|
126
|
+
| `setValue(value)` | `value: string` | `void` | 设置编辑器内容 |
|
|
127
|
+
| `refresh()` | - | `void` | 刷新编辑器布局 |
|
|
128
|
+
| `editor` | - | `IStandaloneCodeEditor` | Monaco Editor 实例 |
|
|
129
|
+
|
|
130
|
+
**JsonEditor 专属事件:**
|
|
131
|
+
|
|
132
|
+
| 事件名 | 参数 | 说明 |
|
|
133
|
+
|--------|------|------|
|
|
134
|
+
| `validate` | `(isValid: boolean, error?: string)` | JSON 验证时触发 |
|
|
135
|
+
|
|
136
|
+
### SqlEditor 专属方法
|
|
137
|
+
|
|
138
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
139
|
+
|--------|------|--------|------|
|
|
140
|
+
| `formatSql()` | - | `void` | 格式化 SQL 代码 |
|
|
141
|
+
| `minifySql()` | - | `void` | 压缩 SQL 代码 |
|
|
142
|
+
| `saveSql()` | - | `void` | 触发保存事件 |
|
|
143
|
+
| `getValue()` | - | `string` | 获取编辑器内容 |
|
|
144
|
+
| `setValue(value)` | `value: string` | `void` | 设置编辑器内容 |
|
|
145
|
+
| `refresh()` | - | `void` | 刷新编辑器布局 |
|
|
146
|
+
| `editor` | - | `IStandaloneCodeEditor` | Monaco Editor 实例 |
|
|
147
|
+
|
|
148
|
+
## 使用示例
|
|
149
|
+
|
|
150
|
+
### 基础用法
|
|
146
151
|
|
|
147
152
|
```vue
|
|
148
153
|
<template>
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
v-model
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
<div>
|
|
155
|
+
<h2>JavaScript 编辑器</h2>
|
|
156
|
+
<JavascriptEditor v-model="jsCode" theme="vs-dark" height="400px" />
|
|
157
|
+
|
|
158
|
+
<h2>JSON 编辑器</h2>
|
|
159
|
+
<JsonEditor v-model="jsonCode" theme="vs" height="400px" />
|
|
160
|
+
|
|
161
|
+
<h2>SQL 编辑器</h2>
|
|
162
|
+
<SqlEditor v-model="sqlCode" theme="vs" height="400px" />
|
|
163
|
+
</div>
|
|
155
164
|
</template>
|
|
156
165
|
|
|
157
|
-
<script setup
|
|
158
|
-
import { ref
|
|
159
|
-
import {
|
|
166
|
+
<script setup>
|
|
167
|
+
import { ref } from 'vue'
|
|
168
|
+
import { JavascriptEditor, JsonEditor, SqlEditor } from '@tuoyuan/code-editor'
|
|
160
169
|
import '@tuoyuan/code-editor/dist/style.css'
|
|
161
170
|
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
// 监听语言变化
|
|
167
|
-
watch(currentLanguage, (newLang) => {
|
|
168
|
-
console.log('语言已切换为:', newLang)
|
|
169
|
-
// 可以根据语言加载不同的代码模板
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
// 监听主题变化
|
|
173
|
-
watch(currentTheme, (newTheme) => {
|
|
174
|
-
console.log('主题已切换为:', newTheme)
|
|
175
|
-
})
|
|
171
|
+
const jsCode = ref('function hello() {\n console.log("Hello")\n}')
|
|
172
|
+
const jsonCode = ref('{"name": "张三", "age": 25}')
|
|
173
|
+
const sqlCode = ref('SELECT * FROM users WHERE age > 18')
|
|
176
174
|
</script>
|
|
177
175
|
```
|
|
178
176
|
|
|
@@ -180,326 +178,395 @@ watch(currentTheme, (newTheme) => {
|
|
|
180
178
|
|
|
181
179
|
```vue
|
|
182
180
|
<template>
|
|
183
|
-
<
|
|
181
|
+
<JavascriptEditor
|
|
184
182
|
v-model="code"
|
|
185
|
-
language="javascript"
|
|
186
183
|
:readonly="true"
|
|
187
|
-
:show-toolbar="false"
|
|
188
184
|
/>
|
|
189
185
|
</template>
|
|
186
|
+
```
|
|
190
187
|
|
|
191
|
-
|
|
192
|
-
import { ref } from 'vue'
|
|
193
|
-
import { CodeEditor } from '@tuoyuan/code-editor'
|
|
194
|
-
import '@tuoyuan/code-editor/dist/style.css'
|
|
188
|
+
### 隐藏工具栏
|
|
195
189
|
|
|
196
|
-
|
|
197
|
-
|
|
190
|
+
```vue
|
|
191
|
+
<template>
|
|
192
|
+
<SqlEditor
|
|
193
|
+
v-model="code"
|
|
194
|
+
:show-toolbar="false"
|
|
195
|
+
/>
|
|
196
|
+
</template>
|
|
198
197
|
```
|
|
199
198
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
| 参数 | 说明 | 类型 | 默认值 |
|
|
205
|
-
| --- | --- | --- | --- |
|
|
206
|
-
| modelValue | 代码内容(支持 v-model) | `string` | `''` |
|
|
207
|
-
| language | 编程语言(支持 v-model:language) | `'javascript' \| 'json' \| 'sql'` | `'javascript'` |
|
|
208
|
-
| theme | 编辑器主题(支持 v-model:theme) | `'vs' \| 'vs-dark' \| 'hc-black'` | `'vs'` |
|
|
209
|
-
| height | 编辑器高度 | `string` | `'400px'` |
|
|
210
|
-
| readonly | 只读模式 | `boolean` | `false` |
|
|
211
|
-
| showToolbar | 显示工具栏(包含语言/主题选择器、格式化、压缩按钮) | `boolean` | `true` |
|
|
212
|
-
| options | Monaco Editor 原生配置项 | `editor.IStandaloneEditorConstructionOptions` | `{}` |
|
|
213
|
-
|
|
214
|
-
**主题说明:**
|
|
215
|
-
- `vs`:浅色主题(白色背景)
|
|
216
|
-
- `vs-dark`:深色主题(黑色背景)
|
|
217
|
-
- `hc-black`:高对比度主题(无障碍模式)
|
|
218
|
-
|
|
219
|
-
### Events
|
|
220
|
-
|
|
221
|
-
| 事件名 | 说明 | 回调参数 | 触发时机 |
|
|
222
|
-
| --- | --- | --- | --- |
|
|
223
|
-
| update:modelValue | 代码内容变化(v-model) | `(value: string) => void` | 每次编辑时 |
|
|
224
|
-
| update:language | 语言变化(v-model:language) | `(language: string) => void` | 切换语言时 |
|
|
225
|
-
| update:theme | 主题变化(v-model:theme) | `(theme: string) => void` | 切换主题时 |
|
|
226
|
-
| change | 代码内容变化 | `(value: string) => void` | 每次编辑时 |
|
|
227
|
-
| blur | 编辑器失焦 | `(value: string) => void` | 失去焦点时 |
|
|
228
|
-
| save | 保存代码 | `(value: string) => void` | 点击保存按钮或按下 Ctrl+S |
|
|
229
|
-
| format | 格式化完成 | `(value: string) => void` | 点击格式化按钮后 |
|
|
230
|
-
| minify | 压缩完成 | `(value: string) => void` | 点击压缩按钮后 |
|
|
231
|
-
| copy | 复制代码 | `(value: string) => void` | 调用 copyCode 方法时 |
|
|
232
|
-
| download | 下载代码 | `(value: string) => void` | 调用 downloadCode 方法时 |
|
|
233
|
-
| fullscreen | 全屏状态变化 | `(isFullscreen: boolean) => void` | 进入/退出全屏时 |
|
|
234
|
-
|
|
235
|
-
### Methods(实例方法)
|
|
236
|
-
|
|
237
|
-
通过 ref 可以调用组件的实例方法:
|
|
199
|
+
### 主题配置
|
|
200
|
+
|
|
201
|
+
组件支持三种主题:`vs`(浅色)、`vs-dark`(暗黑)、`hc-black`(高对比度),默认使用暗黑主题。
|
|
238
202
|
|
|
239
203
|
```vue
|
|
240
204
|
<template>
|
|
241
|
-
<
|
|
205
|
+
<div>
|
|
206
|
+
<!-- 使用默认暗黑主题 -->
|
|
207
|
+
<JavascriptEditor v-model="code1" />
|
|
208
|
+
|
|
209
|
+
<!-- 指定浅色主题 -->
|
|
210
|
+
<JsonEditor v-model="code2" theme="vs" />
|
|
211
|
+
|
|
212
|
+
<!-- 指定高对比度主题 -->
|
|
213
|
+
<SqlEditor v-model="code3" theme="hc-black" />
|
|
214
|
+
|
|
215
|
+
<!-- 通过变量动态控制主题 -->
|
|
216
|
+
<button @click="toggleTheme">切换主题</button>
|
|
217
|
+
<JavascriptEditor v-model="code4" :theme="currentTheme" />
|
|
218
|
+
</div>
|
|
242
219
|
</template>
|
|
243
220
|
|
|
244
|
-
<script setup
|
|
221
|
+
<script setup>
|
|
245
222
|
import { ref } from 'vue'
|
|
246
|
-
import {
|
|
247
|
-
import type { CodeEditorInstance } from '@tuoyuan/code-editor'
|
|
223
|
+
import { JavascriptEditor, JsonEditor, SqlEditor } from '@tuoyuan/code-editor'
|
|
248
224
|
import '@tuoyuan/code-editor/dist/style.css'
|
|
249
225
|
|
|
250
|
-
const
|
|
226
|
+
const code1 = ref('')
|
|
227
|
+
const code2 = ref('')
|
|
228
|
+
const code3 = ref('')
|
|
229
|
+
const code4 = ref('')
|
|
230
|
+
const currentTheme = ref('vs-dark')
|
|
231
|
+
|
|
232
|
+
const toggleTheme = () => {
|
|
233
|
+
currentTheme.value = currentTheme.value === 'vs' ? 'vs-dark' : 'vs'
|
|
234
|
+
}
|
|
251
235
|
</script>
|
|
252
236
|
```
|
|
253
237
|
|
|
254
|
-
|
|
238
|
+
### 使用编辑器方法
|
|
255
239
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
| `enterFullscreen()` | 进入全屏模式 | - | `void` |
|
|
267
|
-
| `exitFullscreen()` | 退出全屏模式 | - | `void` |
|
|
268
|
-
| `editor` | 获取 Monaco Editor 实例 | - | `editor.IStandaloneCodeEditor` |
|
|
240
|
+
```vue
|
|
241
|
+
<template>
|
|
242
|
+
<div>
|
|
243
|
+
<button @click="formatCode">格式化代码</button>
|
|
244
|
+
<button @click="minifyCode">压缩代码</button>
|
|
245
|
+
<button @click="saveCode">保存代码</button>
|
|
246
|
+
|
|
247
|
+
<JavascriptEditor ref="jsEditorRef" v-model="jsCode" />
|
|
248
|
+
</div>
|
|
249
|
+
</template>
|
|
269
250
|
|
|
270
|
-
|
|
251
|
+
<script setup>
|
|
252
|
+
import { ref } from 'vue'
|
|
253
|
+
import { JavascriptEditor } from '@tuoyuan/code-editor'
|
|
254
|
+
import '@tuoyuan/code-editor/dist/style.css'
|
|
271
255
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
editorRef.value?.format()
|
|
256
|
+
const jsEditorRef = ref()
|
|
257
|
+
const jsCode = ref('console.log("Hello")')
|
|
275
258
|
|
|
276
|
-
|
|
277
|
-
|
|
259
|
+
const formatCode = () => {
|
|
260
|
+
jsEditorRef.value.formatJavascript()
|
|
261
|
+
}
|
|
278
262
|
|
|
279
|
-
|
|
280
|
-
|
|
263
|
+
const minifyCode = () => {
|
|
264
|
+
jsEditorRef.value.minifyJavascript()
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const saveCode = () => {
|
|
268
|
+
jsEditorRef.value.saveJavascript()
|
|
269
|
+
}
|
|
270
|
+
</script>
|
|
271
|
+
```
|
|
281
272
|
|
|
282
|
-
|
|
283
|
-
editorRef.value?.setValue('console.log("new code")')
|
|
273
|
+
### JSON 验证
|
|
284
274
|
|
|
285
|
-
|
|
286
|
-
const success = await editorRef.value?.copyCode()
|
|
275
|
+
JsonEditor 组件提供了独特的 JSON 验证功能:
|
|
287
276
|
|
|
288
|
-
|
|
289
|
-
|
|
277
|
+
```vue
|
|
278
|
+
<template>
|
|
279
|
+
<div>
|
|
280
|
+
<button @click="validateJsonData">验证 JSON</button>
|
|
281
|
+
<JsonEditor
|
|
282
|
+
ref="jsonEditorRef"
|
|
283
|
+
v-model="jsonCode"
|
|
284
|
+
@validate="handleValidate"
|
|
285
|
+
/>
|
|
286
|
+
</div>
|
|
287
|
+
</template>
|
|
290
288
|
|
|
291
|
-
|
|
292
|
-
|
|
289
|
+
<script setup>
|
|
290
|
+
import { ref } from 'vue'
|
|
291
|
+
import { JsonEditor } from '@tuoyuan/code-editor'
|
|
292
|
+
import '@tuoyuan/code-editor/dist/style.css'
|
|
293
293
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
editorRef.value?.enterFullscreen() // 进入全屏
|
|
297
|
-
editorRef.value?.exitFullscreen() // 退出全屏
|
|
294
|
+
const jsonEditorRef = ref()
|
|
295
|
+
const jsonCode = ref('{"name": "example"}')
|
|
298
296
|
|
|
299
|
-
|
|
300
|
-
|
|
297
|
+
const validateJsonData = () => {
|
|
298
|
+
const isValid = jsonEditorRef.value.validateJson()
|
|
299
|
+
console.log('JSON 是否有效:', isValid)
|
|
300
|
+
}
|
|
301
301
|
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
const handleValidate = (isValid, error) => {
|
|
303
|
+
if (!isValid) {
|
|
304
|
+
console.error('JSON 验证失败:', error)
|
|
305
|
+
} else {
|
|
306
|
+
console.log('JSON 验证成功')
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
</script>
|
|
304
310
|
```
|
|
305
311
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
### 样式导入
|
|
312
|
+
### 监听事件
|
|
309
313
|
|
|
310
|
-
|
|
314
|
+
```vue
|
|
315
|
+
<template>
|
|
316
|
+
<JavascriptEditor
|
|
317
|
+
v-model="code"
|
|
318
|
+
@change="handleChange"
|
|
319
|
+
@save="handleSave"
|
|
320
|
+
@format="handleFormat"
|
|
321
|
+
@minify="handleMinify"
|
|
322
|
+
/>
|
|
323
|
+
</template>
|
|
311
324
|
|
|
312
|
-
|
|
325
|
+
<script setup>
|
|
326
|
+
import { ref } from 'vue'
|
|
327
|
+
import { JavascriptEditor } from '@tuoyuan/code-editor'
|
|
313
328
|
import '@tuoyuan/code-editor/dist/style.css'
|
|
314
|
-
```
|
|
315
329
|
|
|
316
|
-
|
|
330
|
+
const code = ref('')
|
|
317
331
|
|
|
318
|
-
|
|
332
|
+
const handleChange = (value) => {
|
|
333
|
+
console.log('代码已修改:', value)
|
|
334
|
+
}
|
|
319
335
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
336
|
+
const handleSave = (value) => {
|
|
337
|
+
console.log('保存代码:', value)
|
|
338
|
+
// 这里可以发送到服务器
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const handleFormat = (value) => {
|
|
342
|
+
console.log('代码已格式化:', value)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const handleMinify = (value) => {
|
|
346
|
+
console.log('代码已压缩:', value)
|
|
347
|
+
}
|
|
348
|
+
</script>
|
|
330
349
|
```
|
|
331
350
|
|
|
332
|
-
|
|
351
|
+
### 自定义 Monaco Editor 配置
|
|
333
352
|
|
|
334
|
-
|
|
353
|
+
```vue
|
|
354
|
+
<template>
|
|
355
|
+
<SqlEditor
|
|
356
|
+
v-model="code"
|
|
357
|
+
:options="editorOptions"
|
|
358
|
+
/>
|
|
359
|
+
</template>
|
|
335
360
|
|
|
336
|
-
|
|
361
|
+
<script setup>
|
|
362
|
+
import { ref } from 'vue'
|
|
363
|
+
import { SqlEditor } from '@tuoyuan/code-editor'
|
|
364
|
+
import '@tuoyuan/code-editor/dist/style.css'
|
|
337
365
|
|
|
338
|
-
|
|
366
|
+
const code = ref('')
|
|
339
367
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
368
|
+
const editorOptions = {
|
|
369
|
+
fontSize: 16,
|
|
370
|
+
lineHeight: 24,
|
|
371
|
+
minimap: { enabled: true },
|
|
372
|
+
wordWrap: 'on',
|
|
373
|
+
}
|
|
374
|
+
</script>
|
|
375
|
+
```
|
|
343
376
|
|
|
344
|
-
|
|
345
|
-
- **美化代码按钮**:格式化当前代码
|
|
346
|
-
- **压缩代码按钮**:压缩当前代码(移除空格和换行)
|
|
377
|
+
### 本地存储集成
|
|
347
378
|
|
|
348
|
-
|
|
379
|
+
```vue
|
|
380
|
+
<template>
|
|
381
|
+
<div>
|
|
382
|
+
<JavascriptEditor
|
|
383
|
+
v-model="jsCode"
|
|
384
|
+
v-model:theme="jsTheme"
|
|
385
|
+
@change="saveJsToLocalStorage"
|
|
386
|
+
/>
|
|
387
|
+
|
|
388
|
+
<JsonEditor
|
|
389
|
+
v-model="jsonCode"
|
|
390
|
+
v-model:theme="jsonTheme"
|
|
391
|
+
@change="saveJsonToLocalStorage"
|
|
392
|
+
/>
|
|
393
|
+
</div>
|
|
394
|
+
</template>
|
|
349
395
|
|
|
350
|
-
|
|
396
|
+
<script setup>
|
|
397
|
+
import { ref, onMounted } from 'vue'
|
|
398
|
+
import { JavascriptEditor, JsonEditor } from '@tuoyuan/code-editor'
|
|
399
|
+
import '@tuoyuan/code-editor/dist/style.css'
|
|
351
400
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
401
|
+
const jsCode = ref('')
|
|
402
|
+
const jsTheme = ref('vs')
|
|
403
|
+
const jsonCode = ref('')
|
|
404
|
+
const jsonTheme = ref('vs')
|
|
405
|
+
|
|
406
|
+
onMounted(() => {
|
|
407
|
+
// 从本地存储加载
|
|
408
|
+
jsCode.value = localStorage.getItem('jsCode') || ''
|
|
409
|
+
jsTheme.value = localStorage.getItem('jsTheme') || 'vs'
|
|
410
|
+
jsonCode.value = localStorage.getItem('jsonCode') || ''
|
|
411
|
+
jsonTheme.value = localStorage.getItem('jsonTheme') || 'vs'
|
|
412
|
+
})
|
|
356
413
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
414
|
+
const saveJsToLocalStorage = (value) => {
|
|
415
|
+
localStorage.setItem('jsCode', value)
|
|
416
|
+
localStorage.setItem('jsTheme', jsTheme.value)
|
|
417
|
+
}
|
|
361
418
|
|
|
362
|
-
|
|
419
|
+
const saveJsonToLocalStorage = (value) => {
|
|
420
|
+
localStorage.setItem('jsonCode', value)
|
|
421
|
+
localStorage.setItem('jsonTheme', jsonTheme.value)
|
|
422
|
+
}
|
|
423
|
+
</script>
|
|
424
|
+
```
|
|
363
425
|
|
|
364
|
-
|
|
426
|
+
## TypeScript 支持
|
|
365
427
|
|
|
366
|
-
|
|
367
|
-
- **JSON**:使用 `js-beautify`,自动格式化 JSON 结构
|
|
368
|
-
- **SQL**:使用 `sql-formatter`,格式化 SQL 语句
|
|
428
|
+
组件完全支持 TypeScript,提供完整的类型定义:
|
|
369
429
|
|
|
370
|
-
|
|
430
|
+
```typescript
|
|
431
|
+
import { ref } from 'vue'
|
|
432
|
+
import {
|
|
433
|
+
JavascriptEditor,
|
|
434
|
+
JsonEditor,
|
|
435
|
+
SqlEditor
|
|
436
|
+
} from '@tuoyuan/code-editor'
|
|
437
|
+
import type {
|
|
438
|
+
JavascriptEditorInstance,
|
|
439
|
+
JsonEditorInstance,
|
|
440
|
+
SqlEditorInstance,
|
|
441
|
+
EditorTheme
|
|
442
|
+
} from '@tuoyuan/code-editor'
|
|
443
|
+
|
|
444
|
+
const jsEditorRef = ref<JavascriptEditorInstance>()
|
|
445
|
+
const jsonEditorRef = ref<JsonEditorInstance>()
|
|
446
|
+
const sqlEditorRef = ref<SqlEditorInstance>()
|
|
447
|
+
const theme = ref<EditorTheme>('vs-dark')
|
|
448
|
+
```
|
|
371
449
|
|
|
372
|
-
|
|
373
|
-
| --- | --- |
|
|
374
|
-
| `Ctrl + S` / `Cmd + S` | 保存代码(触发 save 事件) |
|
|
375
|
-
| `ESC` | 退出全屏模式 |
|
|
450
|
+
## 键盘快捷键
|
|
376
451
|
|
|
377
|
-
|
|
452
|
+
- `Ctrl+S` / `Cmd+S`: 保存代码(触发对应的 save 事件)
|
|
378
453
|
|
|
379
|
-
|
|
380
|
-
- 全屏时编辑器会覆盖整个屏幕(`position: fixed`, `z-index: 9999`)
|
|
381
|
-
- 按 `ESC` 键或调用 `exitFullscreen()` 退出全屏
|
|
382
|
-
- 进入/退出全屏时会自动刷新编辑器布局
|
|
454
|
+
## 代码格式化
|
|
383
455
|
|
|
384
|
-
|
|
456
|
+
每个编辑器使用不同的格式化工具:
|
|
385
457
|
|
|
386
|
-
|
|
458
|
+
- **JavascriptEditor**: 使用 `js-beautify` 进行格式化
|
|
459
|
+
- **JsonEditor**: 使用 `js-beautify` 进行格式化
|
|
460
|
+
- **SqlEditor**: 使用 `sql-formatter` 进行格式化
|
|
387
461
|
|
|
388
|
-
|
|
462
|
+
## 组件特点对比
|
|
389
463
|
|
|
390
|
-
|
|
464
|
+
| 特性 | JavascriptEditor | JsonEditor | SqlEditor |
|
|
465
|
+
|------|------------------|------------|-----------|
|
|
466
|
+
| 语言高亮 | ✅ | ✅ | ✅ |
|
|
467
|
+
| 代码格式化 | ✅ | ✅ | ✅ |
|
|
468
|
+
| 代码压缩 | ✅ | ✅ | ✅ |
|
|
469
|
+
| 格式验证 | ❌ | ✅ | ❌ |
|
|
470
|
+
| 主题支持 | ✅ 3种主题 | ✅ 3种主题 | ✅ 3种主题 |
|
|
471
|
+
| 默认主题 | 暗黑 | 暗黑 | 暗黑 |
|
|
472
|
+
| 语言标签颜色 | 黄色 | 蓝色 | 橙色 |
|
|
391
473
|
|
|
392
|
-
|
|
474
|
+
## 浏览器兼容性
|
|
393
475
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
fontSize: 16,
|
|
399
|
-
lineHeight: 24,
|
|
400
|
-
minimap: { enabled: true },
|
|
401
|
-
wordWrap: 'on'
|
|
402
|
-
}"
|
|
403
|
-
/>
|
|
404
|
-
```
|
|
476
|
+
- Chrome >= 90
|
|
477
|
+
- Firefox >= 88
|
|
478
|
+
- Safari >= 14
|
|
479
|
+
- Edge >= 90
|
|
405
480
|
|
|
406
|
-
|
|
481
|
+
## 常见问题
|
|
407
482
|
|
|
408
|
-
###
|
|
483
|
+
### 1. 编辑器高度不正确
|
|
409
484
|
|
|
410
|
-
|
|
485
|
+
确保编辑器的父容器有明确的高度,或者设置 `height` prop:
|
|
411
486
|
|
|
412
487
|
```vue
|
|
413
|
-
|
|
414
|
-
<CodeEditor v-model="code" />
|
|
415
|
-
|
|
416
|
-
<!-- 方式2: @change 事件 -->
|
|
417
|
-
<CodeEditor @change="handleChange" />
|
|
488
|
+
<JavascriptEditor height="500px" v-model="code" />
|
|
418
489
|
```
|
|
419
490
|
|
|
420
|
-
###
|
|
491
|
+
### 2. 如何访问 Monaco Editor 实例?
|
|
421
492
|
|
|
422
|
-
|
|
493
|
+
通过模板引用访问 `editor` 属性:
|
|
423
494
|
|
|
424
495
|
```vue
|
|
425
|
-
<
|
|
496
|
+
<template>
|
|
497
|
+
<JavascriptEditor ref="editorRef" v-model="code" />
|
|
498
|
+
</template>
|
|
426
499
|
|
|
427
500
|
<script setup>
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
501
|
+
import { ref, onMounted } from 'vue'
|
|
502
|
+
|
|
503
|
+
const editorRef = ref()
|
|
504
|
+
|
|
505
|
+
onMounted(() => {
|
|
506
|
+
// 访问 Monaco Editor 实例
|
|
507
|
+
const monacoInstance = editorRef.value.editor
|
|
508
|
+
console.log(monacoInstance)
|
|
509
|
+
})
|
|
433
510
|
</script>
|
|
434
511
|
```
|
|
435
512
|
|
|
436
|
-
###
|
|
513
|
+
### 3. 如何禁用某些编辑器功能?
|
|
514
|
+
|
|
515
|
+
通过 `options` prop 传递 Monaco Editor 配置:
|
|
437
516
|
|
|
438
517
|
```vue
|
|
439
|
-
<
|
|
518
|
+
<SqlEditor
|
|
440
519
|
v-model="code"
|
|
441
|
-
|
|
442
|
-
|
|
520
|
+
:options="{
|
|
521
|
+
minimap: { enabled: false },
|
|
522
|
+
lineNumbers: 'off',
|
|
523
|
+
folding: false
|
|
524
|
+
}"
|
|
443
525
|
/>
|
|
444
526
|
```
|
|
445
527
|
|
|
446
|
-
###
|
|
528
|
+
### 4. Worker 错误如何处理?
|
|
447
529
|
|
|
448
|
-
|
|
530
|
+
组件已经内置了 Worker 配置,无需额外设置。如果遇到问题,请确保:
|
|
449
531
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
<button @click="editorRef?.copyCode()">复制</button>
|
|
454
|
-
<button @click="editorRef?.downloadCode('script.js')">下载</button>
|
|
455
|
-
</template>
|
|
456
|
-
```
|
|
532
|
+
1. 正确引入了样式文件 `@tuoyuan/code-editor/dist/style.css`
|
|
533
|
+
2. 使用的是现代浏览器
|
|
534
|
+
3. 项目构建工具正确处理了静态资源
|
|
457
535
|
|
|
458
|
-
###
|
|
536
|
+
### 5. 三个编辑器可以同时使用吗?
|
|
459
537
|
|
|
460
|
-
|
|
538
|
+
可以。三个编辑器组件是完全独立的,可以在同一页面中同时使用:
|
|
461
539
|
|
|
462
540
|
```vue
|
|
463
|
-
<
|
|
541
|
+
<template>
|
|
542
|
+
<div>
|
|
543
|
+
<JavascriptEditor v-model="jsCode" />
|
|
544
|
+
<JsonEditor v-model="jsonCode" />
|
|
545
|
+
<SqlEditor v-model="sqlCode" />
|
|
546
|
+
</div>
|
|
547
|
+
</template>
|
|
464
548
|
```
|
|
465
549
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
本组件参考了以下项目的实现:
|
|
469
|
-
|
|
470
|
-
1. **devops-platform** (`/src/components/code-editor/`) - Monaco Editor 基础实现
|
|
471
|
-
2. **dashboard-manage.web** (`/src/components/common/Codemirror*`) - UI 设计和功能交互
|
|
472
|
-
|
|
473
|
-
结合了两者的优点:
|
|
474
|
-
- 使用 Monaco Editor 提供强大的编辑器功能和更好的性能
|
|
475
|
-
- 参考 Codemirror 组件的 UI 设计和用户交互体验
|
|
476
|
-
- 内置 Worker 配置,零配置即可使用
|
|
477
|
-
|
|
478
|
-
## 📝 版本历史
|
|
550
|
+
### 6. 如何区分不同编辑器的方法?
|
|
479
551
|
|
|
480
|
-
|
|
481
|
-
- ✅ 初始版本发布
|
|
482
|
-
- ✅ 支持 JavaScript、JSON、SQL 语言
|
|
483
|
-
- ✅ 支持代码高亮、格式化、压缩
|
|
484
|
-
- ✅ 内置工具栏(语言/主题选择器、格式化、压缩)
|
|
485
|
-
- ✅ 底部状态栏(光标位置、统计信息、保存按钮)
|
|
486
|
-
- ✅ 支持主题切换(浅色、深色、高对比度)
|
|
487
|
-
- ✅ 支持复制、下载、全屏功能
|
|
488
|
-
- ✅ 支持 Ctrl+S 保存快捷键
|
|
489
|
-
- ✅ 完整的 TypeScript 类型定义
|
|
490
|
-
- ✅ 内置 Monaco Editor Worker 配置
|
|
552
|
+
每个编辑器都有专属的方法名,避免混淆:
|
|
491
553
|
|
|
492
|
-
|
|
554
|
+
- JavaScript: `formatJavascript()`, `minifyJavascript()`, `saveJavascript()`
|
|
555
|
+
- JSON: `formatJson()`, `minifyJson()`, `saveJson()`, `validateJson()`
|
|
556
|
+
- SQL: `formatSql()`, `minifySql()`, `saveSql()`
|
|
493
557
|
|
|
494
|
-
|
|
558
|
+
## 许可证
|
|
495
559
|
|
|
496
|
-
|
|
560
|
+
MIT
|
|
497
561
|
|
|
498
|
-
|
|
562
|
+
## 更新日志
|
|
499
563
|
|
|
500
|
-
|
|
564
|
+
### 1.0.0 (2024-01-01)
|
|
501
565
|
|
|
502
|
-
-
|
|
503
|
-
-
|
|
504
|
-
-
|
|
505
|
-
-
|
|
566
|
+
- 🎉 首次发布
|
|
567
|
+
- ✨ 提供三个独立编辑器组件:JavascriptEditor、JsonEditor、SqlEditor
|
|
568
|
+
- 🎨 支持三种主题切换
|
|
569
|
+
- 📝 代码格式化和压缩功能
|
|
570
|
+
- 🔍 JSON 格式验证功能
|
|
571
|
+
- 🔧 完整的 TypeScript 支持
|
|
572
|
+
- 📦 开箱即用的 Worker 配置
|