Vue component for editing Vue components with interactive REPL functionality.
—
The editor system provides a pluggable architecture with two implementations: CodeMirror for lightweight editing and Monaco for full language service support. Both editors conform to a standard interface for seamless switching.
Standard interface that all editor components must implement for pluggable editor support.
/**
* Standard props interface for all editor components
*/
interface EditorProps {
/** Current file content to display */
value: string;
/** Filename for language detection and display */
filename: string;
/** Whether editor should be read-only */
readonly?: boolean;
/** Override automatic language mode detection */
mode?: EditorMode;
}
/**
* Events emitted by editor components
*/
interface EditorEmits {
/** Emitted when editor content changes */
(e: 'change', code: string): void;
}
/**
* Editor component type constraint
*/
type EditorComponentType = Component<EditorProps>;
/**
* Editor display modes for compiled output
*/
type EditorMode = 'js' | 'css' | 'ssr';Lightweight editor implementation using CodeMirror 5 with syntax highlighting and basic editing features.
Package Import:
import CodeMirror from "@vue/repl/codemirror-editor";Features:
Usage Examples:
import { Repl } from "@vue/repl";
import CodeMirror from "@vue/repl/codemirror-editor";
// Basic usage
<template>
<Repl :editor="CodeMirror" />
</template>
// With additional props
<template>
<Repl
:editor="CodeMirror"
theme="dark"
:showCompileOutput="false"
/>
</template>CodeMirror Modes:
The CodeMirror editor automatically maps file extensions to appropriate modes:
const modes = {
'css': 'css',
'html': 'htmlmixed',
'js': { name: 'javascript' },
'json': { name: 'javascript', json: true },
'ts': { name: 'javascript', typescript: true },
'vue': 'htmlmixed'
};Full-featured editor implementation using Monaco Editor with Volar language service integration.
Package Import:
import Monaco from "@vue/repl/monaco-editor";Features:
Usage Examples:
import { Repl } from "@vue/repl";
import Monaco from "@vue/repl/monaco-editor";
// Basic usage with Monaco
<template>
<Repl :editor="Monaco" />
</template>
// With Monaco-specific options
<template>
<Repl
:editor="Monaco"
:editorOptions="{
monacoOptions: {
fontSize: 14,
minimap: { enabled: false },
scrollBeyondLastLine: false,
wordWrap: 'on'
}
}"
/>
</template>Monaco Options:
Monaco editor supports extensive configuration through editorOptions.monacoOptions:
interface MonacoOptions {
/** Font size in pixels */
fontSize?: number;
/** Font family */
fontFamily?: string;
/** Enable/disable minimap */
minimap?: { enabled: boolean };
/** Word wrapping */
wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded';
/** Line numbers display */
lineNumbers?: 'on' | 'off' | 'relative' | 'interval';
/** Enable/disable folding */
folding?: boolean;
/** Scroll beyond last line */
scrollBeyondLastLine?: boolean;
/** Tab size */
tabSize?: number;
/** Use spaces instead of tabs */
insertSpaces?: boolean;
// ... many more options available
}Choose the appropriate editor based on your use case:
Use CodeMirror when:
Use Monaco when:
Comparison:
| Feature | CodeMirror | Monaco |
|---|---|---|
| Bundle Size | ~100KB | ~2MB |
| Language Service | None | Full Volar |
| Autocomplete | Basic | IntelliSense |
| Error Detection | Compilation only | Real-time |
| Performance | Faster startup | Heavier but rich |
| Mobile Support | Better | Good |
Both editors integrate seamlessly with the REPL system:
Automatic Features:
View State Persistence:
// Editor state is automatically preserved when switching files
// Cursor position, scroll position, and selections are maintained
// Access current file's editor state
const activeFile = store.activeFile;
console.log(activeFile.editorViewState); // Monaco editor state objectYou can create custom editor components by implementing the EditorComponentType interface:
// Custom editor component
<script setup lang="ts">
import type { EditorProps, EditorEmits } from "@vue/repl";
const props = defineProps<EditorProps>();
const emit = defineEmits<EditorEmits>();
// Editor implementation
const handleChange = (newValue: string) => {
emit('change', newValue);
};
</script>
<template>
<!-- Custom editor implementation -->
<div class="custom-editor">
<textarea
:value="props.value"
@input="handleChange($event.target.value)"
/>
</div>
</template>Both editors handle various error conditions gracefully:
CodeMirror Error Handling:
Monaco Error Handling:
CodeMirror Performance:
Monaco Performance:
Optimization Tips:
// Optimize Monaco for better performance
<Repl
:editor="Monaco"
:editorOptions="{
monacoOptions: {
// Disable expensive features for better performance
minimap: { enabled: false },
codeLens: false,
scrollBeyondLastLine: false,
// Limit suggestions for faster autocomplete
quickSuggestions: {
other: false,
comments: false,
strings: false
}
}
}"
/>Install with Tessl CLI
npx tessl i tessl/npm-vue--repl