vue实现codemirror sql
Vue 中集成 CodeMirror 实现 SQL 编辑器
安装依赖
需要安装 codemirror 核心库及 SQL 模式插件:
npm install codemirror @codemirror/lang-sql
基础组件实现
创建 Vue 组件文件(如 SqlEditor.vue):
<template>
<div ref="editorContainer"></div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { EditorView, basicSetup } from 'codemirror'
import { sql } from '@codemirror/lang-sql'
export default {
setup() {
const editorContainer = ref(null)
let editorView = null
onMounted(() => {
editorView = new EditorView({
doc: 'SELECT * FROM table',
extensions: [
basicSetup,
sql(),
EditorView.updateListener.of(update => {
if (update.docChanged) {
console.log(update.state.doc.toString())
}
})
],
parent: editorContainer.value
})
})
onBeforeUnmount(() => {
editorView?.destroy()
})
return { editorContainer }
}
}
</script>
自定义 SQL 语法高亮
通过扩展语法配置实现更精细的 SQL 高亮:
import { sql, MySQL } from '@codemirror/lang-sql'
const extensions = [
basicSetup,
sql({
dialect: MySQL,
upperCaseKeywords: true
}),
EditorView.theme({
'&': { height: '300px' },
'.cm-scroller': { fontFamily: 'monospace' }
})
]
添加自动补全功能
集成 SQL 自动补全需要自定义补全源:
import { autocompletion } from '@codemirror/autocomplete'
const sqlCompletion = sql().language.data.of({
autocomplete: context => {
const keywords = ['SELECT', 'FROM', 'WHERE', 'INSERT', 'UPDATE']
const match = context.matchBefore(/\w*/)
if (!match) return null
return {
from: match.from,
options: keywords.map(word => ({
label: word,
type: "keyword"
}))
}
}
})
// 在 extensions 中添加
extensions.push(autocompletion({ override: [sqlCompletion] }))
处理编辑器值变化
双向绑定实现方案:
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
// 在 EditorView 配置中添加
extensions.push(
EditorView.updateListener.of(update => {
if (update.docChanged) {
emit('update:modelValue', update.state.doc.toString())
}
})
)
// 初始化时设置初始值
editorView = new EditorView({
doc: props.modelValue || '',
// ...其他配置
})
响应式布局处理
添加窗口大小变化的响应式处理:
import { debounce } from 'lodash-es'
onMounted(() => {
const handleResize = debounce(() => {
editorView?.requestMeasure()
}, 200)
window.addEventListener('resize', handleResize)
onBeforeUnmount(() => window.removeEventListener('resize', handleResize))
})
主题定制示例
使用 Material 主题的配置方式:
import { oneDark } from '@codemirror/theme-one-dark'
extensions.push(
oneDark,
EditorView.theme({
'.cm-activeLine': { backgroundColor: '#37414b' },
'.cm-gutters': { backgroundColor: '#282c34' }
})
)
以上实现方案提供了从基础集成到高级定制的完整路径,可根据实际需求选择功能模块组合使用。注意在组件销毁时调用 editorView.destroy() 防止内存泄漏。







