<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue2 Ace Editor</title>
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<!-- 引入 vue2-ace-editor -->
<script src="https://unpkg.com/vue2-ace-editor@0.0.13/dist/vue2-ace-editor.min.js"></script>
<!-- 引入 Ace Editor -->
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/ace.js"></script>
<!-- 引入 Ace Editor 主题 -->
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/theme-monokai.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/theme-dracula.js"></script>
<!-- 引入 Ace Editor 模式 -->
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/mode-javascript.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/mode-json.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/mode-html.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/mode-css.js"></script>
<!-- 引入 Element UI -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<style>
.el-card__header {
padding: 20px;
}
.el-select {
width: 130px;
margin-right: 20px;
}
.el-button {
margin-right: 10px;
}
.editor-container {
border: 1px solid #e8e8e8;
min-height: 300px;
}
</style>
</head>
<body>
<div id="app">
<div ref="screenFull">
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<span>代码编辑器</span>
</div>
<div style="display: flex; width: 100%; margin-bottom: 10px;">
<el-select
v-model="valueTheme"
placeholder="选择主题"
filterable
clearable
@change="selectTheme"
>
<el-option
v-for="item in listTheme"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-select
v-model="valueCodeLang"
placeholder="选择语言"
filterable
clearable
@change="selectLang"
>
<el-option
v-for="item in listCodeLang"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-select
v-model="valueFontSize"
placeholder="字体大小"
filterable
clearable
@change="selectFontSize"
>
<el-option
v-for="item in listFontSize"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-button type="primary" icon="el-icon-document-copy" @click="copyCode">复制</el-button>
<el-button v-if="valueCodeLang === 'json'" type="primary" icon="el-icon-view" @click="formatCode">美化</el-button>
<el-button type="primary" :icon=" fullScreen ? 'el-icon-full-screen' : 'el-icon-crop' " @click="screen">{{ fullScreen ? '退出全屏' : '全屏' }}</el-button>
</div>
<div class="editor-container">
<editor
ref="aceEditor"
v-model="content"
@init="editorInit"
width="100%"
:height="editorHight + 'px'"
:lang="lang"
:theme="theme"
:options="{
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
tabSize: 4,
fontSize: fontSize,
readOnly: readOnly,
showPrintMargin: false
}"
></editor>
</div>
</el-card>
</div>
</div>
<script>
// 注册组件
Vue.component('editor', window['vue2-ace-editor']);
new Vue({
el: '#app',
data() {
return {
listTheme: [
'clouds',
'clouds_midnight',
'dracula',
'chrome',
'chaos',
'xcode',
'monokai',
'ambiance',
'dreamweaver',
'eclipse',
'github',
'idle_fingers'
],
listCodeLang: [
'json',
'yaml',
'xml',
'java',
'text',
'javascript',
'scheme',
'lua',
'mysql',
'perl',
'powershell',
'python',
'ruby',
'sql',
'hjson',
'ini'
],
listFontSize: [10, 12, 14, 16, 20],
content: '',
valueTheme: 'clouds',
valueCodeLang: 'json',
valueFontSize: 12,
theme: 'clouds',
lang: 'json',
fontSize: 12,
tmpFontSize: 12,
fullScreen: false,
unFullEditorHight: 300,
editorHight: 300,
appendToBody: true,
readOnly: false
};
},
methods: {
selectTheme(newValue) {
this.theme = newValue;
},
selectLang(newValue) {
this.lang = newValue;
},
selectFontSize(newValue) {
this.fontSize = newValue;
this.tmpFontSize = newValue;
},
editorInit() {
const langTools = ace.require('ace/ext/language_tools');
ace.config.setModuleUrl('ace/ext/language_tools', 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/ext-language_tools.js');
ace.config.setModuleUrl('ace/ext/beautify', 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict/ext-beautify.js');
langTools.addCompleter({
getCompletions: (editor, session, pos, prefix, callback) => {
callback(null, []);
}
});
},
copyCode() {
const code = this.$refs.aceEditor.editor.getValue();
if (navigator.clipboard) {
navigator.clipboard.writeText(code);
this.$message.success('复制成功');
} else {
this.$message.error('您的浏览器不支持自动复制,请手动复制');
}
},
formatCode() {
const code = this.$refs.aceEditor.editor.getValue();
if (code !== '') {
const string = JSON.stringify(JSON.parse(code), null, 2);
this.$refs.aceEditor.editor.setValue(string);
}
},
screen() {
this.valueFontSize = this.fontSize = 12;
const element = this.$refs.screenFull;
if (this.fullScreen) {
this.appendToBody = true;
this.editorHight = this.unFullEditorHight;
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
} else {
this.appendToBody = false;
this.editorHight = window.screen.availHeight - 50;
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
this.fullScreen = !this.fullScreen;
}
}
});
</script>
</body>
</html>