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
为双向绑定编辑器内容
这样一个编辑器就搞定了。示例代码中只是使用了部分配置项,更多配置或者高级用法参考官方配置加入进来就好啦(▽)