• vuejs - - - - - 使用code编辑器codemirror


    0. 效果图

    列表实现参考: 列表实现代码
    在这里插入图片描述
    在这里插入图片描述

    1. 依赖安装

    npm install codemirror codemirror-editor-vue3 jsonlint-mod
    在这里插入图片描述
    在这里插入图片描述

    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>
    
    
    • 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
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    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>
    
    • 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
  • 相关阅读:
    【kali-漏洞利用】(3.2)Metasploit基础(中):Armitage工具利用过程
    uniapp+vue基于Android的图书馆借阅系统qb4y3-nodejs-php-pyton
    xss-labs/level12
    MySQL 基础语法(2)
    js 模拟鼠标移动事件,并监听鼠标移动
    数据结构——排序算法——插入排序
    线上Timeout waiting for connection from pool问题分析和解决方案
    MATLAB算法实战应用案例精讲-【图像处理】SLAM技术详解(最终篇)
    New Work New Life
    camunda_01_documents
  • 原文地址:https://blog.csdn.net/Dark_programmer/article/details/133172522