Ace Editor

Ace是一个功能非常强大的编辑器。它实现了语法着色,缩进,代码提示功能。且具有大量的主题,支持大量语言。但是官方并没有提供vue的官方版本,不过跟 vue 集成的步骤并不复杂。

相关网址

1、官方地址

实现效果

在这里插入图片描述

具体实现

1、首先需要执行命令 npm install ace-builds -S 安装依赖
2、创建一个名称为 codeEditor.vue 文件,代码如下

<template>
  <div class="wrap h-100">
    <div class="w-100 code-editor" :ref="generateId"></div>
    <span v-if="withFullscreenBtn" title="全屏显示">
      <svg-icon
        class="icon-fullscreen"
        icon-class="fullscreen"
        :style="{ bottom: (withFooterBtns ? 47 : 10) + 'px' }"
        @click.native="fullscreen"
      ></svg-icon>
    </span>

    <el-dialog
      ref="dialog"
      custom-class="code-dialog"
      :visible.sync="isVisible"
      title="脚本编辑"
      fullscreen
      append-to-body
      :show-footer="false"
      @close="closeEditCode"
    >
      <code-editor v-model="dialogValue"></code-editor>
    </el-dialog>
  </div>
</template>
<script>
// 引入全局实例
import ace from 'ace-builds'
// 主题风格,引入主题后还需要在 options 中指定主题才会生效
import 'ace-builds/src-min-noconflict/theme-monokai'
import 'ace-builds/src-min-noconflict/theme-dracula'
// 支持代码格式, 需要引入具体的语法高亮库才会有对应的语法高亮效果
import 'ace-builds/src-min-noconflict/mode-javascript'
import 'ace-builds/src-min-noconflict/mode-json'
import 'ace-builds/src-min-noconflict/mode-css'
import 'ace-builds/src-min-noconflict/ext-language_tools'
import jsWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-javascript'
import jsonWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-json'
import cssWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-css'
ace.config.setModuleUrl('ace/mode/javascript_worker', jsWorkerUrl)
ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerUrl)
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl)
ace.config.setModuleUrl(
  'ace/snippets/javascript',
  require('file-loader!ace-builds/src-noconflict/snippets/javascript.js')
)
ace.config.setModuleUrl('ace/snippets/css', require('file-loader!ace-builds/src-noconflict/snippets/css.js'))

import { cloneDeep } from '@/utils/tool'
export default {
  name: 'CodeEditor',
  model: {
    event: 'change'
  },
  props: {
  	// 编辑器内容
    value: String,
    // 默认语言
    language: {
      type: String,
      default: 'javascript'
    },
    // 主题,对应主题库 JS 需要提前引入
    theme: {
      type: String,
      default: 'monokai'
    },
    // 是否只读
    readonly: {
      type: Boolean,
      default: false
    },
    // 最大行数
    maxLines: Number,
    // 是否显示全屏按钮
    withFullscreenBtn: {
      type: Boolean,
      default: false
    },
    withFooterBtns: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      editor: null,
      generateId:
        'id_' +
        Math.random()
          .toString(36)
          .substr(2, 4),
      isVisible: false,
      dialogValue: ''
    }
  },
  mounted() {
  	// 初始化
    this.initEditor()
  },
  watch: {
    value(val) {
      if (this.editor.getValue() !== val) {
        this.editor.setValue(val)
        this.editor.clearSelection()
      }
    }
  },
  methods: {
  	// 初始化
    initEditor() {
      // 创建实例
      this.editor = ace.edit(this.$refs[this.generateId], {
        mode: `ace/mode/${this.language}`,
        theme: `ace/theme/${this.theme}`,
        fontSize: 12,
        tabSize: 2,
        value: this.value,
        selectionStyle: 'text',
        maxLines: this.maxLines,
        readOnly: this.readonly
      })
      // 设置属性等,具体需要可根据官方参数自行设置
      this.editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        wrap: true,
        setShowPrintMargin: false
      })
      // 设置值改变监听
      this.editor.on('change', () => {
        this.$emit('change', this.editor.getValue())
      })
    },
    // 实例方法,高亮某一行
    gotoLine(lineNumber) {
      this.editor.gotoLine(lineNumber)
    },
    // 全屏编辑
    fullscreen() {
      this.dialogValue = cloneDeep(this.editor.getValue())
      this.isVisible = true
    },
    closeEditCode() {
      this.editor.setValue(this.dialogValue)
      this.editor.clearSelection()
    },
    // resize编辑器
    resize() {
      this.editor.resize(true)
    },
    destroy() {
      if (this.editor) {
        this.editor.destroy()
        this.editor = null
      }
    }
  },
  beforeDestroy() {
    this.destroy()
  }
}
</script>
<style lang="scss" scoped>
.wrap {
  position: relative;
  .code-editor {
    min-height: 200px;
    height: 100%;
    border: 1px solid #282f3a;
    background-color: #0e1013;
  }
  .icon-fullscreen {
    position: absolute;
    // color: #fff;
    right: 10px;
    font-size: 16px;
    z-index: 9999;
    cursor: pointer;
  }
}
/deep/ .code-dialog {
  &::before {
    content: '';
    position: absolute;
    display: block;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 2px;
    background-image: linear-gradient(270deg, #00deff, #2483ff 74%);
  }
  display: flex;
  flex-direction: column;
  background-color: #303640;
  .el-dialog__header {
    border: none;
    .el-dialog__title {
      color: #ccc;
    }
  }
  .el-dialog__body {
    flex: 1 1 0;
    padding-top: 10px;
  }
}
</style>

使用

1、在页面中引入 ,并注册组件
import CodeEditor from '@/components/CodeEditor'

2、使用

<code-editor ref="_firstRefs" class="editor h-100" v-model="editorContent"
            readonly language="json" theme="dracula"></code-editor>

其中 editorContent 为双向绑定编辑器内容

这样一个编辑器就搞定了。示例代码中只是使用了部分配置项,更多配置或者高级用法参考官方配置加入进来就好啦()

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐