赞
踩
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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。