Vue.js - 集成CodeMirror实现代码编辑器功能(语言高亮、关键字高亮)
作者:hangge | 2025-12-18 08:50
CodeMirror 是一个功能强大的代码编辑器内核(基于浏览器),常用于在线代码编辑、配置编辑器、富文本差异显示等场景。它支持丰富的语言高亮、主题、快捷键、扩展(addon)等。下面我将演示在 Vue 项目中如何集成 CodeMirror,包括把 CodeMirror 封装为一个组件,支持 v-model(双向绑定)、外部配置传入和事件回调,方便复用。
(2)运行效果如下,可以看到代码已经具有语法高亮效果,并且我们可以自由编辑。

(2)如果希望只读模式下光标也不显示,那么可以将 readOnly 属性设置为 'nocursor'
(2)下面是官方内置主题完整列表:
(3)下面样例我们改用 idea 浅色主题进行代码高亮显示,修改 CodeMirrorEditor.vue 组件。
(4)最后显示效果如下:
(2)下面表格整理了市面上常用语言以及对应的 mode:
(3)假设我们需要实现 sql 语言高亮,首先在 CodeMirrorEditor.vue 组件中引入对应 mode 的 js。
(4)然后使用该组件时将 mode 设置为'sql'
(5)最后效果如下图所示:
1,安装依赖
进入项目的根目录,执行如下命令安装 CodeMirror v5 版本:
npm install codemirror@5
2,封装一个自定义组件
为方便使用,我们创建一个 CodeMirrorEditor.vue 组件,支持 v-model、传入 options、外部更新同步和卸载清理。
<template>
<div class="cm-wrapper">
<!-- 使用 textarea 以便后续销毁时能调用 toTextArea() 安全销毁 -->
<textarea ref="textarea"></textarea>
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css' // 基础样式
import 'codemirror/theme/dracula.css' // 可选主题
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/xml/xml.js' // html 使用 xml 或 htmlmixed
import 'codemirror/mode/css/css.js'
import 'codemirror/addon/edit/closebrackets.js' // 自动闭合括号
import 'codemirror/addon/comment/comment.js' // 注释快捷键
import 'codemirror/addon/fold/foldcode.js' // 折叠
import 'codemirror/addon/selection/active-line.js'// 当前行高亮
export default {
name: 'CodeMirrorEditor',
props: {
value: { type: String, default: '' }, // 绑定的文本内容
options: { type: Object, default: () => ({}) } //CodeMirror初始化配置(lineNumbers, mode等)
},
mounted() {
// // 合并默认配置
const defaultOptions = {
value: this.value || '',
lineNumbers: true,
mode: 'javascript',
theme: 'dracula',
autoCloseBrackets: true
}
// 用 fromTextArea 创建编辑器,便于销毁
this.editor = CodeMirror.fromTextArea(this.$refs.textarea,
Object.assign({}, defaultOptions, this.options))
// 初始化后主动设置一次内容
if (this.value) {
this.editor.setValue(this.value)
}
// 编辑器内容变化时向外发出input事件
this.editor.on('change', () => {
const val = this.editor.getValue()
this.$emit('input', val)
})
},
watch: {
// 如果外部 modelValue 变更(非来自编辑器),同步到编辑器
value(newVal) {
if (!this.editor) return
if (this.editor.getValue() !== newVal) {
this.editor.setValue(newVal || '')
}
}
},
// 组件卸载,销毁编辑器并恢复 textarea
beforeDestroy() {
if (this.editor && typeof this.editor.toTextArea === 'function') {
this.editor.toTextArea()
this.editor = null
}
}
}
</script>
<style scoped>
.cm-wrapper .CodeMirror {
height: 400px;
}
</style>
3,使用样例
(1)下面是用这个自定义组件,并传入初始内容:
<template>
<CodeMirrorEditor v-model="code" :options="{ mode: 'javascript', lineNumbers: true }" />
</template>
<script>
import CodeMirrorEditor from './codemirror/CodeMirrorEditor.vue'
export default {
components: { CodeMirrorEditor },
data() {
return {
code: `const users = [
{ id: 1, name: 'Alice',s: 30 }
]
// 箭头函数
const getUserNames = () => users.map(u => u.name)
// async / await 示例
async function loadUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const user = users.find(u => u.id === id)
user ? resolve(user) : reject(new Error('Not found'))
}, 500)
})
}`
}
}
}
</script>
(2)运行效果如下,可以看到代码已经具有语法高亮效果,并且我们可以自由编辑。

附:进阶技巧
1,只读模式
(1)如果希望只能展示不能编辑,可以将 CodeMirror 的 readOnly 属性设置为 true,此时编辑器不可输入、可选中、可复制。但该模式下还是有鼠标光标。
<CodeMirrorEditor v-model="code" :options="{
mode: 'javascript',
lineNumbers: true,
readOnly: true }"
/>

<CodeMirrorEditor v-model="code" :options="{
mode: 'javascript',
lineNumbers: true,
readOnly: 'nocursor'}"
/>
2,设置主题样式
(1)前面的样例我们使用的是 dracula 这个暗色主题。CodeMirror 自带了很多官方主题,不需要额外 npm 安装,只要 import 对应的 .css 就能用。想要知道本地有哪些主题可以打开项目如下路径查看:
node_modules/codemirror/theme/
(2)下面是官方内置主题完整列表:
| 深色主题 | 浅色主题 |
|
3024-night
abbott
abcdef
ambiance
ayu-dark
base16-dark
bespin
blackboard
cobalt
colorforth
darcula
dracula
duotone-dark
elegant
erlang-dark
hopscotch
icecoder
isotope
lesser-dark
liquibyte
lucario
material
material-darker
material-ocean
material-palenight
monokai
night
nord
oceanic-next
panda-syntax
paraiso-dark
railscasts
rubyblue
seti
shadowfox
the-matrix
tomorrow-night-bright
tomorrow-night-eighties
ttcn
twilight
vibrant-ink
xq-dark
yonce
zenburn
|
3024-day
base16-light
default
eclipse
idea
mdn-like
neo
paraiso-light
ssms
yeti
xq-light
|
(3)下面样例我们改用 idea 浅色主题进行代码高亮显示,修改 CodeMirrorEditor.vue 组件。
<template>
<div class="cm-wrapper">
<!-- 使用 textarea 以便后续销毁时能调用 toTextArea() 安全销毁 -->
<textarea ref="textarea"></textarea>
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css' // 基础样式
import 'codemirror/theme/idea.css' // 可选主题
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/xml/xml.js' // html 使用 xml 或 htmlmixed
import 'codemirror/mode/css/css.js'
import 'codemirror/addon/edit/closebrackets.js' // 自动闭合括号
import 'codemirror/addon/comment/comment.js' // 注释快捷键
import 'codemirror/addon/fold/foldcode.js' // 折叠
import 'codemirror/addon/selection/active-line.js'// 当前行高亮
export default {
name: 'CodeMirrorEditor',
props: {
value: { type: String, default: '' }, // 绑定的文本内容
options: { type: Object, default: () => ({}) } //CodeMirror初始化配置(lineNumbers, mode等)
},
mounted() {
// // 合并默认配置
const defaultOptions = {
value: this.value || '',
lineNumbers: true,
mode: 'javascript',
theme: 'idea',
autoCloseBrackets: true
}
// 用 fromTextArea 创建编辑器,便于销毁
this.editor = CodeMirror.fromTextArea(this.$refs.textarea,
Object.assign({}, defaultOptions, this.options))
// 初始化后主动设置一次内容
if (this.value) {
this.editor.setValue(this.value)
}
// 编辑器内容变化时向外发出input事件
this.editor.on('change', () => {
const val = this.editor.getValue()
this.$emit('input', val)
})
},
watch: {
// 如果外部 modelValue 变更(非来自编辑器),同步到编辑器
value(newVal) {
if (!this.editor) return
if (this.editor.getValue() !== newVal) {
this.editor.setValue(newVal || '')
}
}
},
// 组件卸载,销毁编辑器并恢复 textarea
beforeDestroy() {
if (this.editor && typeof this.editor.toTextArea === 'function') {
this.editor.toTextArea()
this.editor = null
}
}
}
</script>
<style scoped>
.cm-wrapper .CodeMirror {
height: 400px;
}
</style>
(4)最后显示效果如下:
3,设置语言 mode
(1)CodeMirror v5 的语言高亮是通过 mode 实现的。其自带的 mode 非常多,覆盖了几乎所有常见编程/标记/配置语言。要查看完整 mode 列表,可以打开项目的如下路径。这下面每一个文件夹都是一个可用 mode。
node_modules/codemirror/mode/
(2)下面表格整理了市面上常用语言以及对应的 mode:
| 语言 | Mode 名 | Import 路径 |
|---|---|---|
| JavaScript | javascript | codemirror/mode/javascript/javascript.js |
| TypeScript | javascript | codemirror/mode/javascript/javascript.js |
| JSON | javascript | codemirror/mode/javascript/javascript.js |
| HTML | htmlmixed | codemirror/mode/htmlmixed/htmlmixed.js |
| CSS | css | codemirror/mode/css/css.js |
| Vue | htmlmixed | 同 HTML(依赖 xml / js / css) |
| Markdown | markdown | codemirror/mode/markdown/markdown.js |
| YAML | yaml | codemirror/mode/yaml/yaml.js |
| XML | xml | codemirror/mode/xml/xml.js |
| Java | clike | codemirror/mode/clike/clike.js |
| C / C++ | clike | codemirror/mode/clike/clike.js |
| C# | clike | codemirror/mode/clike/clike.js |
| Go | go | codemirror/mode/go/go.js |
| Python | python | codemirror/mode/python/python.js |
| PHP | php | codemirror/mode/php/php.js |
| Ruby | ruby | codemirror/mode/ruby/ruby.js |
| Shell / Bash | shell | codemirror/mode/shell/shell.js |
| PowerShell | powershell | codemirror/mode/powershell/powershell.js |
| SQL | sql | codemirror/mode/sql/sql.js |
| Redis | redis | codemirror/mode/redis/redis.js |
| Nginx | nginx | codemirror/mode/nginx/nginx.js |
| Dockerfile | dockerfile | codemirror/mode/dockerfile/dockerfile.js |
| TOML | toml | codemirror/mode/toml/toml.js |
| INI / Conf | properties | codemirror/mode/properties/properties.js |
| Less | less | codemirror/mode/css/css.js |
| SCSS / Sass | sass / scss | codemirror/mode/sass/sass.js |
| Stylus | stylus | codemirror/mode/stylus/stylus.js |
| JSX | jsx | codemirror/mode/jsx/jsx.js |
| Handlebars | handlebars | codemirror/mode/handlebars/handlebars.js |
| Pug | pug | codemirror/mode/pug/pug.js |
| CSV | spreadsheet | codemirror/mode/spreadsheet/spreadsheet.js |
| Diff | diff | codemirror/mode/diff/diff.js |
| LaTeX | stex | codemirror/mode/stex/stex.js |
import 'codemirror/mode/sql/sql.js'
(4)然后使用该组件时将 mode 设置为'sql'
<CodeMirrorEditor v-model="code" :options="{
mode: 'sql',
lineNumbers: true
}" />
(5)最后效果如下图所示:

全部评论(0)