需求: CodeMirror 编辑器实现Tab键自动补全 默认的是Enter键自动补全
想要实现上图效果 按Tab键自动补全 原生写法
利用keymap.of 配置Tab键实现
<template>
<div class="container" id="code-container"></div>
</template>
<script setup>
import { EditorState } from '@codemirror/state'
import { basicSetup } from 'codemirror'
import { EditorView } from '@codemirror/view'
import { onMounted } from 'vue'
import { sql } from '@codemirror/lang-sql'
import { ViewUpdate, keymap } from '@codemirror/view'
import { acceptCompletion } from '@codemirror/autocomplete'
let state = EditorState.create({
extensions: [
basicSetup,
sql(), // 配置的sql语法 会给sql语法提示
keymap.of([
{
key: 'Tab',
run: acceptCompletion, // 接受自动补全
},
]),
],
// 编辑器中的内容
doc: '',
})
onMounted(() => {
let view = new EditorView({
state,
// 编辑器 挂载的dom
parent: document.querySelector('#code-container'),
})
})
</script>
<style>
.container {
width: 1400px;
height: 700px;
}
</style>
对应的npm包 "@codemirror/autocomplete": "^6.12.0", "@codemirror/lang-sql": "6.5.4", "@codemirror/view": "^6.23.0",
用vue-codemirror包的实现方式
<template>
<div class="mm">
<Codemirror
v-model="sqlCode"
:style="{ width: '100%', height: '550px' }"
:extensions="extensions"
:indent-with-tab="false"
/>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { sql } from '@codemirror/lang-sql'
import {
autocompletion,
acceptCompletion,
moveCompletionSelection,
} from '@codemirror/autocomplete'
import { ViewUpdate, keymap } from '@codemirror/view'
let extensions = ref([
sql(),
keymap.of([
{
key: 'Tab',
run: acceptCompletion,
},
]),
])
const sqlCode = ref('')
</script>
<style>
.mm {
width: 1400px;
height: 700px;
border: 1px solid pink;
color: #111;
background-color: #fff;
}
</style>
CodeMirror 代码编辑器禁用 只读模式
通过EditorView.editable.of(false) 一句代码就可以设置为不可以编辑 只读,EditorView引自@codemirror/view.
<template>
<div class="mm">
<Codemirror
v-model="sqlCode"
:style="{ width: '100%', height: '550px' }"
:extensions="extensions"
:indent-with-tab="false"
/>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { sql } from '@codemirror/lang-sql'
import {
autocompletion,
acceptCompletion,
moveCompletionSelection,
} from '@codemirror/autocomplete'
import { ViewUpdate, keymap, EditorView } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
let editable = false
let extensions = ref([
sql(),
keymap.of([
{
key: 'Tab',
run: acceptCompletion,
},
]),
EditorView.editable.of(false),
EditorState.readOnly.of(true),
])
const sqlCode = ref('')
</script>
<style>
.mm {
width: 1400px;
height: 700px;
border: 1px solid pink;
color: #111;
background-color: #fff;
}
</style>
周末找了挺久 记录下~
获取鼠标选中代码
2024/5/16
通过update事件,sliceDoc()方法就可以获取。子组件 封装一些配置
<template>
<Codemirror
v-model="sqlCode"
:placeholder="editorPlaceholder"
:style="editorStyle"
:autofocus="true"
:disabled="disabled"
:indent-with-tab="true"
:tabSize="tabSize"
:extensions="extensions"
:scrollbarStyle="null"
@ready="handleReady"
@update="handleCmUpdate"
/>
</template>
<script setup>
import { Codemirror } from 'vue-codemirror'
import { sql } from '@codemirror/lang-sql'
import { ViewUpdate, keymap, EditorView } from '@codemirror/view'
import {
autocompletion,
acceptCompletion,
moveCompletionSelection,
} from '@codemirror/autocomplete'
const props = defineProps({
modelValue: {
type: String,
default: '',
},
editorPlaceholder: {
type: String,
default: '请输入sql语句',
},
editorStyle: {
type: Object,
default: () => ({ width: '300px', height: '200px' }),
},
tabSize: {
type: Number,
default: 2,
},
disabled: {
type: Boolean,
default: false,
},
isDisable: {
type: Boolean,
default: false,
},
})
const emits = defineEmits([
'change',
'update:modelValue',
'ready',
'handleCmUpdate',
])
const sqlCode = computed({
get() {
return props.modelValue
},
set(value) {
emits('update:modelValue', value)
},
})
let extensions = ref([
sql(),
keymap.of([
{
key: 'Tab',
run: acceptCompletion,
},
]),
// 配置是否只读
EditorView.editable.of(props.isDisable ? false : true),
])
// Codemirror EditorView instance ref
const view = shallowRef()
const handleReady = payload => {
emits('ready', payload)
}
const handleCmUpdate = val => {
emits('handleCmUpdate', val)
}
</script>
<style>
.ͼb {
color: #fc0505;
}
</style>
父组件通过子组件update过来的事件,通过sliceDoc就可以获取选中的代码,然后只执行选中的代码
<sql-codemirror
v-model="ddlContent"
:editorStyle="{ width: '100%', height: '350px' }"
editorPlaceholder=""
class="mt-20"
:isDisable="true"
@handleCmUpdate="handleCmUpdate"
></sql-codemirror>
// 定义选中代码
let selectedCode = ref('')
// 获取选中代码
const handleCmUpdate = view => {
selectedCode.value = view.state.sliceDoc(
view.state.selection.main.from,
view.state.selection.main.to
)
}