• vue中使用CodeMirror解析yaml语言


    一、CodeMirror插件使用

    1.CodeMirror插件安装

    下载插件:npm install codemirror @5.59.1
    这里使用的是codemirror5,现在codemirror最新已经是6了,不过参考文档相对较少,使用起来不是那么方便。后续文档丰富之后可以考虑使用6

    二、CodeMirror基本配置

    这里使用到的配置如下

        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'
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三、CodeMirror具体使用

    1.首先创建一个textarea标签

    <textarea ref="textarea" v-model="code"></textarea>
    
    • 1

    2.然后引入相关依赖

    // 基础依赖
    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'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.最后初始化编辑器

    	// 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)
          })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、CodeMirror语法校验

    1.引入语法校验依赖

    // 语法校验基础依赖
    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'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    codemirror支持的校验库如下
    在这里插入图片描述

    2.配置options中开启校验

    // 是否开启语法校验
    lint: true,
    // 使用的语法校验工具
    gutters: ['CodeMirror-lint-markers'],
    
    • 1
    • 2
    • 3
    • 4

    3.安装lint需要的其他依赖

    仅仅是这样还是不够的,因为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>
    
    
    • 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
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145

    具体使用:

    <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>
    
    
    • 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
  • 相关阅读:
    新零售SaaS架构:订单履约系统的概念模型设计
    排序学习(Learning to rank)综述
    Python中json.loads()无法解析单引号字符串问题的两种解决方法
    el-checkbox复选框如何修改尺寸大小
    图解LeetCode——7. 整数反转(难度:中等)
    Python爬虫:原理与实战
    二分查找:74搜索二维矩阵
    力扣数据库题库学习(4.24日)
    openlayers 绘制tin数据导文
    Altium designer—快速改变丝印字符大小
  • 原文地址:https://blog.csdn.net/weixin_43845090/article/details/125403699