monaco-editor编辑器使用方法(vue3实现)
1、首先在vue3项目中安装monaco-editor
yarn add monaco-editor
yarn add monaco-editor-webpack-plugin
2、封装编辑器组件:包括运行、复制、重置功能(运行功能下一篇更新)
主要是初始化编辑器,创建dom,配置相关参数。
<template>
<div class="left-box">
<div class="left-top">
<div class="run">
<div class="btn" v-if="codeType == 'HTML'" @click="runClick">运行</div>
</div>
<div class="title-center">
<div class="title" @click="clickHtml('Vue')" :style="{ color: codeType == 'Vue' ? '#066fdb' : '#fbfbfb' }">Vue代码</div>
<div class="title" style="margin: 0 10px">|</div>
<div class="title" @click="clickHtml('HTML')" :style="{ color: codeType == 'HTML' ? '#066fdb' : '#fbfbfb' }">HTML代码</div>
</div>
<div class="copy">
<div class="btn" @click="reset">重置</div>
<div class="btn" @click="copy">复制</div>
</div>
</div>
<div id="codeEditBox" class="codeEditBox"></div>
</div>
</template>
<script>
import * as monaco from "monaco-editor";
import { toRaw } from "vue";
import { ref, defineComponent, watch } from "vue";
import $ from "jquery";
export default defineComponent({
props: {
code: {
type: String,
default: "",
},
cardName: {
type: String,
default: "",
},
codeType: {
type: String,
default: "",
},
},
setup(props, { emit }) {
let changeValue = ref("");
const editor = ref(null);
const codeType = ref("Vue");
const initEditor = () => {
// 初始化编辑器,确保dom已经渲染
editor.value = monaco.editor.create(document.getElementById("codeEditBox"), {
value: props.code, //编辑器初始显示文字
language: props.cardName == "HTML" ? "html" : "javascript", //语言支持自行查阅demo
theme: "vs-dark", //官方自带三种主题vs, hc-black, or vs-dark
selectOnLineNumbers: true, //显示行号
roundedSelection: false,
readOnly: false, // 只读
cursorStyle: "line", //光标样式
automaticLayout: false, //自动布局
glyphMargin: true, //字形边缘
useTabStops: false,
fontSize: 14, //字体大小
autoIndent: true, //自动布局
quickSuggestionsDelay: 100, //代码提示延时
automaticLayout: true, //自适应,
});
// 监听值的变化
editor.value.onDidChangeModelContent((event) => {
//拿到变化后的值
changeValue.value = getVal();
});
};
watch(
() => props.code,
(newValue, oldValue) => {
// 值发生变化时的回调函数
toRaw(editor.value).setValue(newValue);
},
{ deep: true, immediate: false }
);
watch(
() => props.codeType,
(newValue) => {
if (newValue == "HTML") {
monaco.editor.setModelLanguage(editor.value.getModel(), "html");
} else {
monaco.editor.setModelLanguage(editor.value.getModel(), "javascript");
}
},
{ deep: true, immediate: false }
);
//复制到电脑剪切板
const copyToClipboard = (textToCopy) => {
navigator.clipboard
.writeText(textToCopy)
.then(() => {
console.log("已成功复制到剪贴板");
})
.catch((error) => {
console.error("复制到剪贴板失败:", error);
});
};
const clickHtml = (data) => {
codeType.value = data;
emit("clickHtml", data);
};
const copy = () => {
copyToClipboard(getVal());
};
const reset = () => {
toRaw(editor.value).setValue(props.code);
};
$(document).ready(function () {
initEditor();
});
const getVal = () => {
return toRaw(editor.value).getValue(); //获取编辑器中的文本
};
//运行
const runClick = () => {
emit("customEvent", changeValue.value);
};
return {
editor,
getVal,
changeValue,
copy,
reset,
copyToClipboard,
runClick,
clickHtml,
codeType,
};
},
});
</script>
<style scoped lang="scss">
.left-box {
width: 100%;
height: 100%;
}
.title-center {
display: flex;
justify-content: space-between;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.left-top {
height: 6%;
width: 100%;
color: azure;
background-color: black;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
}
.copy {
display: flex;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.btn {
margin-left: 10px;
}
}
.run {
color: #ffffff;
height: 100%;
width: 80px;
display: flex;
align-items: center;
justify-content: center;
}
.btn {
cursor: pointer;
}
#codeEditBox {
width: 100%;
height: 94%;
}
</style>