vue2项目使用codemirror插件实现代码编辑器功能

本文介绍了如何在Vue.js应用中使用npm安装并集成CodeMirror代码编辑器,提供了详细的配置步骤,包括引入样式、设置语言模式、自定义快捷键和代码提示等功能,并展示了Vue2和Vue3(使用TypeScript)两种不同版本的组件实现。通过示例代码,演示了如何在组件中创建和配置CodeMirror实例,以及监听代码变化事件。
摘要由CSDN通过智能技术生成

1、使用npm安装依赖

npm install --save codemirror

2、在页面中放入如下代码

<template>
  <textarea ref="mycode" class="codesql" v-model="code" style="height:200px;width:600px;"></textarea>
</template>

<script>
  import "codemirror/theme/ambiance.css";
  import "codemirror/lib/codemirror.css";
  import "codemirror/addon/hint/show-hint.css";

  let CodeMirror = require("codemirror/lib/codemirror");
  require("codemirror/addon/edit/matchbrackets");
  require("codemirror/addon/selection/active-line");
  require("codemirror/mode/sql/sql");
  require("codemirror/addon/hint/show-hint");
  require("codemirror/addon/hint/sql-hint");
    export default {
        name: "codeMirror",
      data () {
        return {
          code: '//按Ctrl键进行代码提示'
        }
      },
      mounted () {
        debugger
        let mime = 'text/x-mariadb'
        //let theme = 'ambiance'//设置主题,不设置的会使用默认主题
        let editor = CodeMirror.fromTextArea(this.$refs.mycode, {
          mode: mime,//选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
          indentWithTabs: true,
          smartIndent: true,
          lineNumbers: true,
          matchBrackets: true,
          //theme: theme,
          // autofocus: true,
          extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
          hintOptions: {//自定义提示选项
            tables: {
              users: ['name', 'score', 'birthDate'],
              countries: ['name', 'population', 'size']
            }
          }
        })
        //代码自动提示功能,记住使用cursorActivity事件不要使用change事件,这是一个坑,那样页面直接会卡死
        editor.on('cursorActivity', function () {
          editor.showHint()
        })
      }
    }
</script>

<style>
  .codesql {
    font-size: 11pt;
    font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
  }
</style>

vue2 ts 类装饰版本组件

<template>
  <textarea ref="container" v-model="value"></textarea>
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Ref, Model, Emit, Watch, Prop } from 'vue-property-decorator';
import CodeMirror from 'codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/sql/sql';
import 'codemirror/theme/neat.css';
import 'codemirror/addon/scroll/simplescrollbars.css';
import 'codemirror/addon/scroll/simplescrollbars';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/sql-hint';
import 'codemirror/mode/meta';
import 'codemirror/addon/selection/active-line';

@Component
export default class CodeEditor extends Vue {
  @Ref('container') container!: HTMLTextAreaElement;

  @Model('change') value!: string;

  @Prop(Array) list?: string[];

  @Prop(Number) ch?: number;

  @Prop(String) height?: string;

  mirror: CodeMirror.Editor = CodeMirror(this.container);

  constructor() {
    super();
    this.changeListener = this.changeListener.bind(this);
  }

  mounted() {
    this.mirror = CodeMirror.fromTextArea(this.container, {
      value: this.value,
      mode: 'text/x-sql',
      theme: 'neat',
      styleActiveLine: true,
      readOnly: false,
      smartIndent: true,
      scrollbarStyle: 'overlay',
      lineNumbers: true,
      // matchBrackets: true,
      autofocus: true,
      // autoMatchParens: true,
      // styleSelectedText: true,
      indentUnit: 4,
      extraKeys: { Ctrl: 'autocomplete' },
      showHint: true,
      autocorrect: true,
      autocapitalize: true,
    });

    this.mirror.setSize('heigth', this.height);
    this.mirror.on('change', this.changeListener);
  }

  private changeListener(editor: CodeMirror.Editor, change: CodeMirror.EditorChangeLinkedList) {
    this.handleContentChange(this.mirror.getValue());
    if (change.origin === '+input' || change.origin === '*compose') {
      setTimeout(() => {
        const cursor = editor.getCursor();
        const str = editor.getLine(cursor.line);

        if (this.list && this.list.length) {
          // eslint-disable-next-line
          const hint = () => {
            return {
              from: { ch: this.ch || str.lastIndexOf(' ') + 1, line: cursor.line },
              to: { ch: str.length, line: cursor.line },
              list: [...(this.list || ['allen'])],
            };
          };
          editor.showHint({
            completeSingle: false,
            hint,
          });
        } else {
          this.mirror.showHint({ completeSingle: false, hint: CodeMirror.hint.sql });
        }
      }, 20);
    }
  }

  @Watch('value')
  handleValueChange(newValue: string) {
    if (newValue !== this.mirror.getValue()) {
      if (!newValue) {
        this.mirror.setValue('');
        return;
      }
      const value = newValue
        .split(' ')
        .filter((item) => !!item)
        .join(' ');
      this.mirror.setValue(value);
      this.mirror.focus();
      this.mirror.setCursor(newValue.length);
    }
  }

  @Emit('change')
  handleContentChange(content: string) {
    return content;
  }

  beforeDestroy() {
    this.mirror.off('change', this.changeListener);
  }
}
</script>

<style lang="less">
.CodeMirror {
  line-height: 1.5;
}
</style>

3、话不多说,直接上图

 

 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yusirxiaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值