办学质量监测教学评价系统
shenrongliang
2025-06-13 11d86cc6c26bb4f709e407acadf4805c2024e79f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<script setup lang="ts">
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
import CodeMirror from 'vue-codemirror6';
 
import { usePreferences } from '@vben/preferences';
 
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
 
import { type LanguageSupport, languageSupportMap } from './data';
 
const props = withDefaults(
  defineProps<{
    /**
     * 语言
     */
    language: LanguageSupport;
    /**
     * 只读
     */
    readonly?: boolean;
  }>(),
  {
    language: 'js',
    readonly: false,
  },
);
 
const codeMirrorRef =
  useTemplateRef<InstanceType<typeof CodeMirror>>('codeMirrorRef');
 
const { isDark } = usePreferences();
 
const modelValue = defineModel({ default: '', type: String });
 
const lang = computed(() => languageSupportMap[props.language] ?? javascript());
 
// 通过v-if 卸载挂载达到更新语言的目的
const langChanged = ref(true);
watch(
  () => props.language,
  () => {
    langChanged.value = false;
    nextTick(() => (langChanged.value = true));
  },
);
/** 插件 */
const extensions = [oneDark];
</script>
 
<template>
  <CodeMirror
    v-if="langChanged"
    v-bind="$attrs"
    ref="codeMirrorRef"
    v-model="modelValue"
    :dark="isDark"
    :extensions="extensions"
    :lang="lang"
    :readonly="props.readonly"
    basic
    wrap
  >
    <template v-for="slotName in Object.keys($slots)" #[slotName]="scope">
      <slot :name="slotName" v-bind="scope ?? {}"></slot>
    </template>
  </CodeMirror>
</template>