美文网首页GIS加油站
vconsole助力实现在线代码编辑调试

vconsole助力实现在线代码编辑调试

作者: 牛老师讲webgis | 来源:发表于2024-04-03 17:43 被阅读0次

    概述

    前面有文章monaco-editor做自己的代码测试工具 ,本文书接前文,在代码中加入vconsole工具,可以进行代码调试、查看网络、查看元素等。

    效果

    demo.png

    vconsole简介

    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>
    

    参考引用

    相关文章

      网友评论

        本文标题:vconsole助力实现在线代码编辑调试

        本文链接:https://www.haomeiwen.com/subject/lhbgtjtx.html