使用code编辑器codemirror
- 0. 效果图
- 1. 依赖安装
- 2. 组件封装
- 3. 组件使用
0. 效果图
列表实现参考: 列表实现代码
1. 依赖安装
npm install codemirror codemirror-editor-vue3 jsonlint-mod
2. 组件封装
code-mirror-editor.vue
<template><VueCodeMirrorclass="json-editor"ref="CodeMirrorRef":options="state.cmOptions"v-model:value="state.value"v-bind="$attrs"@keydown="onKeyDown"@mousedown="onMouseDown"@change="onChange"/>
</template>
<script lang="ts" setup>
import VueCodeMirror, { CmComponentRef } from 'codemirror-editor-vue3';
import { Form } from 'ant-design-vue';
// language
import 'codemirror/mode/javascript/javascript.js';
// theme 主题
import 'codemirror/theme/monokai.css';
// 折叠功能
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/brace-fold.js';
// 自动提示
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/javascript-hint.js';
// 代码校验 lint
import 'codemirror/addon/lint/lint.js';
import 'codemirror/addon/lint/lint.css';
import 'codemirror/addon/lint/json-lint';
import jsonlint from 'jsonlint-mod';// 其他
import 'codemirror/addon/edit/matchbrackets.js';
import 'codemirror/addon/edit/closebrackets.js';(window as any).jsonlint = jsonlint;const props: any = defineProps({value: String,options: {type: Object,default: () => ({}),},
});const emit = defineEmits(['update:visible', 'update:value']);
const CodeMirrorRef = ref<CmComponentRef>(null);
// 初始配置项
const cmDefaultOptions = {mode: 'application/javascript',theme: 'default',matchBrackets: true, //括号匹配autoCloseBrackets: true, // 自动补齐styleActiveLine: true, //line选择是是否高亮lineNumbers: true, //是否显示行数lineWrapping: true, //是否自动换行readOnly: false,matchTags: { bothTags: true }, // 将突出显示光标周围的标签lint: true,foldGutter: true, // 可将对象折叠,与下面的gutters一起使用gutters: ['CodeMirror-foldgutter'],hintOptions: {completeSingle: false,}, // 提示配置
};
const state = reactive({value: props.value,cmOptions: { ...cmDefaultOptions, ...props.options },
});
// 添加props的value变化
watch(() => props.value,values => {state.value = values;},{ immediate: true, deep: true },
);
// Form 校验
const formItemContext = Form.useInjectFormItemContext();
const onChange = (value: string) => {emit('update:value', value);formItemContext.onFieldChange();
};const onKeyDown = event => {const keyCode = event.keyCode || event.which || event.charCode;const keyCombination = event.ctrlKey || event.altKey || event.metaKey;if (!keyCombination && keyCode > 64 && keyCode < 123) {CodeMirrorRef.value?.cminstance.showHint({ completeSingle: false });}
};const onMouseDown = () => {CodeMirrorRef.value?.cminstance.closeHint();
};
</script>
<style>
.CodeMirror * {font-family: monospace;font-size: 14px;
}
</style>
<style lang="less" scoped>
.json-editor {max-height: 320px;overflow-y: scroll;
}
.codemirror-container {width: 100%;
}
.CodeMirror {width: 100% !important;
}
:deep(.ant-form-item) {height: 100%;.ant-form-item-control-input {height: 100%;}.ant-form-item-control-input-content {height: 100%;}
}
</style>
3. 组件使用
<template><CodeMirrorEditor:value="getRequestCode"class="code-editor"@update:value="rewriteValues($event, 'requestParam')"/>
</template><script>
const formState = reactive({requestParam: []
})/*** 实时计算:将对应参数的值转换成对应code*/
const getRequestCode = computed(() => {return JSON.stringify(formState.requestParam, null, 2);
});/*** 编辑器编辑:code => 序列化后重新赋值*/
function rewriteValues(val: string, formKey: string) {formState[formKey] = JSON.parse(val);
}</script><style lang="less">
.code-editor {border: 1px solid #d9d9d9;min-height: 200px;overflow-y: scroll;:deep(.CodeMirror) {min-height: 200px;// max-height: 800px;.CodeMirror-sizer {margin-left: 32px !important;}.CodeMirror-gutter-wrapper {left: -45px !important;}.CodeMirror-linenumbers {width: 21px !important;}}:deep(.CodeMirror-scroll) {min-height: 200px;// max-height: 800px;}
}
</style>