概述
前面有文章monaco-editor做自己的代码测试工具 ,本文书接前文,在代码中加入vconsole
工具,可以进行代码调试、查看网络、查看元素等。
效果
demo.pngvconsole简介
vconsole
是一个轻量、可拓展、针对手机网页的前端开发者调试面板。跟框架无关的,可以在 Vue、React 或其他任何框架中使用。具有如下功能特性:
- 日志(Logs): console.log|info|error|...
- 网络(Network): XMLHttpRequest, Fetch, sendBeacon
- 节点(Element): HTML 节点树
- 存储(Storage): Cookies, LocalStorage, SessionStorage
- 手动执行 JS 命令行
- 自定义插件
实现
1. 编辑器组件
编辑器的实现前面的文章有介绍过,本文在此基础上做了优化,实现代码如下:
<template>
<div class="editor-title">
{{ editorTitle }}
</div>
<div class="editor-content" :id="`${language}Editor`"></div>
</template>
<script>
import * as monaco from "monaco-editor";
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json') {
return new jsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker();
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker();
}
return new editorWorker();
},
};
let editorInstance = {}
export default {
computed: {
editorTitle() {
return this.title || this.language
}
},
mounted() {
this.initEditor()
},
props: {
title: {
type: String,
default: ''
},
language: {
type: String,
default: ''
},
value: {
type: String,
default: ''
}
},
methods: {
initEditor() {
const dom = document.getElementById(`${this.language}Editor`)
editorInstance[this.language] = monaco.editor.create(dom, {
value: this.value,
theme: "vs-dark",
language: this.language,
fontSize: 14
});
},
getCode() {
return editorInstance[this.language]?.getValue() || ''
},
}
}
</script>
<style scoped lang="scss">
$height: 2rem;
.editor-title {
height: $height;
line-height: $height;
background-color: #003f8f;
color: #fff;
padding: 0 0.5rem;
font-size: 1rem;
font-weight: bold;
}
.editor-content {
height: calc(100% - #{$height});
width: 100%;
}
</style>
注意:在实现编辑器组件的时候,发现在data
中定义编辑器实例在调用getValue()
的时候会出现卡死的现象,但是如果定义一个变量的话,获取到的值是最后一个编辑器的值。
2. 引用组件,实现
代码的运行预览通过iframe
实现,引用组件实现的完整代码如下:
<template>
<div class="editor-content">
<button class="tools-button" @click="runCode">运行</button>
<div class="editor">
<Editor language="html" ref="htmlEditor"></Editor>
</div>
<div class="editor">
<Editor language="css" ref="cssEditor"></Editor>
</div>
<div class="editor">
<Editor language="javascript" ref="jsEditor"></Editor>
</div>
</div>
<iframe id="preview" frameborder="0" class="preview-content"></iframe>
</template>
<script>
import Editor from './components/Editor.vue'
export default {
components: {
Editor
},
mounted() {
this.runCode()
},
methods: {
runCode() {
const htmlCode = this.$refs.htmlEditor.getCode()
const cssCode = this.$refs.cssEditor.getCode()
const jsCode = this.$refs.jsEditor.getCode()
const srcdoc = `
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
height: calc(100% - 15rem);
}
.console {
height: 15rem;
}
.vc-mask {
display: none !important;
}
.vc-panel {
left: auto;
bottom: auto !important;
height: 100%;
width: 100%;
}
${cssCode}
</style>
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"><\/script>
</head>
<body>
<div class="container">
${htmlCode}
</div>
<div class="console" id="console"></div>
<script>
// 创建调试器
const target = document.getElementById('console')
const vConsole = new window.VConsole({
defaultPlugins: ['network', 'element', 'storage'],
target
});
setTimeout(() => {
vConsole.hideSwitch();
vConsole.show()
}, 100)
${jsCode}
<\/script>
</body>
</html>`
console.log({
htmlCode,
cssCode,
jsCode
})
const preview = document.getElementById('preview')
preview.setAttribute("srcdoc", srcdoc);
}
}
}
</script>
<style lang="scss">
.editor-content, .preview-content {
height: 100%;
width: 50%;
float: left;
position: relative;
.editor {
height: calc(100% / 3)
}
.tools-button {
position: absolute;
right: 5px;
top: 3px;
z-index: 100;
}
}
</style>
网友评论