下载插件:npm install codemirror @5.59.1
这里使用的是codemirror5,现在codemirror最新已经是6了,不过参考文档相对较少,使用起来不是那么方便。后续文档丰富之后可以考虑使用6
这里使用到的配置如下
const options = {
mode: 'yaml',
// 缩进格式
tabSize: 2,
// 主题,对应主题库 JS 需要提前引入
theme: 'base16-dark',
// 行号码
lineNumbers: true,
line: true,
readOnly: false,
// 是否开启语法校验
lint: true,
// 使用的语法校验工具
gutters: ['CodeMirror-lint-markers'],
// 光标背景行高亮
styleActiveLine: true,
// 自动刷新
autoRefresh: true,
height: '500px'
}
<textarea ref="textarea" v-model="code"></textarea>
// 基础依赖
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
// 语法模式 这里我使用的是yaml,各位按需引入(json、html等等)
import 'codemirror/mode/${props.mode}/yaml.js'
// 主题样式
import 'codemirror/theme/base16-dark.css'
// 自动刷新依赖
import 'codemirror/addon/display/autorefresh'
// 行高亮依赖
import 'codemirror/addon/selection/active-line'
// textarea为textarea标签的ref,vue3写法
const textarea = ref(null)
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
coder = CodeMirror.fromTextArea(textarea.value, options)
coder.on('blur', coder => {
// 获取文本内容
const newValue = coder.getValue()
// 抛出事件
emit('update:modelValue', newValue)
})
// 语法校验基础依赖
import 'codemirror/addon/lint/lint.js'
import 'codemirror/addon/lint/lint.css'
// yaml校验js,按需引入(json-lint、html-lint等)
import 'codemirror/addon/lint/yaml-lint.js'
codemirror支持的校验库如下
// 是否开启语法校验
lint: true,
// 使用的语法校验工具
gutters: ['CodeMirror-lint-markers'],
仅仅是这样还是不够的,因为codemirror对应的校验插件中可能还依赖其他的库
比如yaml:
可以看到他还依赖js-yaml,所以我们需要下载js-yaml插件 npm install js-yaml
在代码中引入: import jsYaml from 'js-yaml'
绑定到window上 window.jsyaml = jsYaml
其他语法也类似,例如json需要json-lint,然后绑定到window.jsonlint上:
我将codemirror封装为一个vue3组件,各位可以参考一下
<template>
<div class="in-coder-panel">
<textarea ref="textarea" v-model="code"></textarea>
</div>
</template>
<script>
import { onMounted, ref, watch } from 'vue'
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/addon/lint/yaml-lint.js'
import jsYaml from 'js-yaml'
window.jsyaml = jsYaml
export default {
components: {},
props: {
modelValue: {
type: String,
default: ``
},
mode: {
type: String,
default: 'javascript'
},
lint: {
// codemirror仅支持html、css、json、javascript、yaml这几种,请手动引入,且需要下载相关插件,具体插件参考源码(node_modules/codemirror/addon/lint/)或官方文档
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
// 主题
theme: {
type: String,
default: 'base16-dark' // 编辑器主题色
},
// 高亮选中行
styleActiveLine: {
type: Boolean,
default: true
},
// 自动刷新
autoRefresh: {
type: Boolean,
default: true
}
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const textarea = ref(null)
const code = ref(props.modelValue)
// 编辑器实例
let coder
watch(
() => props.modelValue,
val => {
coder?.setValue(val)
}
)
const options = {
mode: props.mode,
// 缩进格式
tabSize: 2,
// 主题,对应主题库 JS 需要提前引入
theme: props.theme,
// 行号码
lineNumbers: true,
line: true,
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
readOnly: props.readonly,
lint: props.lint,
gutters: ['CodeMirror-lint-markers'],
// 光标背景行高亮
styleActiveLine: props.styleActiveLine,
// 自动刷新
autoRefresh: props.autoRefresh,
height: '500px'
}
const initialize = async () => {
try {
// 动态引入相关依赖
await import(`codemirror/theme/${props.theme}.css`)
if (props.lint) {
await import('codemirror/addon/lint/lint.js')
await import('codemirror/addon/lint/lint.css')
}
if (props.mode) {
await import(`codemirror/mode/${props.mode}/${props.mode}.js`)
}
if (props.autoRefresh) {
await import('codemirror/addon/display/autorefresh')
}
if (props.styleActiveLine) {
await import('codemirror/addon/selection/active-line')
}
} catch (e) {
console.log(e)
}
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
coder = CodeMirror.fromTextArea(textarea.value, options)
coder.on('blur', coder => {
const newValue = coder.getValue()
emit('update:modelValue', newValue)
})
}
onMounted(() => {
initialize()
})
const checkYaml = async val => {
jsYaml.load(val)
}
return {
code,
options,
textarea,
checkYaml
}
}
}
</script>
<style lang="scss" scoped>
.in-coder-panel {
width: 100%;
height: 100%;
:deep(.CodeMirror) {
border: 1px solid #eee;
height: 100%;
width: 100%;
.CodeMirror-code {
line-height: 19px;
}
}
}
</style>
<style>
.CodeMirror-lint-tooltip {
z-index: 10000 !important;
}
</style>
具体使用:
<template>
<div>
<base-codemirror
ref="yamlRef"
v-model="code"
mode="yaml"
style="height: 200px"
:lint="true"
:readonly="true"
></base-codemirror>
<el-button @click="btnClick">点击</el-button>
</div>
</template>
<script>
import BaseCodemirror from '@/components/Base/BaseCodemirror'
import { ref } from 'vue'
export default {
name: 'Demo',
components: {
BaseCodemirror
},
setup() {
const yamlRef = ref(null)
const code = ref(`apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
deprecated.daemonset.template.generation: "1"
field.cattle.io/creatorId: user-jsgrs
creationTimestamp: "2022-05-16T03:08:58Z"
generation: 1
labels:
cattle.io/creator: norman
workload.user.cattle.io/workloadselector: daemonSet-default-asdf`)
const btnClick = () => {
yamlRef.value.checkYaml(code).then(() => {
console.log(11)
})
}
return {
code,
yamlRef,
btnClick
}
}
}
</script>
<style scoped></style>