0. 效果图
列表实现参考: 列表实现代码
1. 依赖安装
2. 组件封装
code-mirror-editor.vue
<template>
<vuecodemirror
class="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>
发表评论