一、简介

本文主要介绍如何开发一个同echarts官网里面在线echarts编辑工具,通过页面中的代码编辑器修改echarts的option属性来实时渲染echarts的展示效果。其中主要使用到了【monaco-editor】这个组件。

下图为完成的效果图:

二、如何实现

  • 引入monaco-editor包

    npm install monaco-editor
    npm install monaco-editor-webpack-plugin
    
  • 编辑器组件封装

    通过引入monaco-editor组件,然后进行指定dom节点以及配置进行页面渲染,该组件通过v-model绑定编辑器的内容。

    monaco-editor官方文档:https://microsoft.github.io/monaco-editor/api/modules/monaco.html

    <template>
      <div id="jsMonacoEditor" ref="main" />
    </template>
    
    <script>
    import * as monaco from 'monaco-editor'
    
    /*
    * @Description: monacoEditor组件封装
    * @Author: linmt
    * @Date: @Date: 2022-09-11 08:45:55
    */
    export default {
      name: 'JsMonacoEditor',
      components: {
      },
      model: { // 使用v-model绑定编辑器的内容
        prop: 'value',
        event: 'change'
      },
      props: {
        value: {
          type: String,
          default: ''
        }
      },
      data() {
        return {
          monacoEditor: null
        }
      },
      computed: {
    
      },
      watch: {
        value() {
          this.init()
        }
      },
      created() {
    
      },
      mounted() {
        this.init()
      },
      methods: {
        /**
         * 初始化
         */
        init() {
          if (this.monacoEditor) {
            return
          }
    
          this.monacoEditor = monaco.editor.create(this.$refs.main, {
            theme: 'vs', // 主题
            value: this.value, // 默认显示的值
            language: 'javascript',
            folding: true, // 是否折叠
            foldingHighlight: true, // 折叠等高线
            foldingStrategy: 'indentation', // 折叠方式  auto | indentation
            showFoldingControls: 'always', // 是否一直显示折叠 always | mouseover
            disableLayerHinting: true, // 等宽优化
            emptySelectionClipboard: false, // 空选择剪切板
            selectionClipboard: false, // 选择剪切板
            automaticLayout: true, // 自动布局
            codeLens: false, // 代码镜头
            scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
            colorDecorators: true, // 颜色装饰器
            accessibilitySupport: 'off', // 辅助功能支持  "auto" | "off" | "on"
            lineNumbers: 'on', // 行号 取值: "on" | "off" | "relative" | "interval" | function
            lineNumbersMinChars: 5, // 行号最小字符   number
            enableSplitViewResizing: false,
            readOnly: false, // 是否只读  取值 true | false
            minimap: {
              enabled: true // 是否启用预览图
            } // 预览图设置
          })
    
          const self = this
          
          // _.debounce为lodashjs工具包的方法,见https://www.lodashjs.com/
          // 主要用来防抖动
          const changeValueFun = _.debounce(function() {
            self.changeValue()
          }, 500)
    
    	  // 监听编辑器内容改变事件
          this.monacoEditor.onDidChangeModelContent((e) => {
            changeValueFun()
          })
        },
        changeValue() {
          this.$emit('change', this.monacoEditor.getValue())
        }
      }
    }
    
    </script>
    <style lang='scss' scoped>
    #jsMonacoEditor{
      height: 100%;
      width: 100%;
    }
    </style>
    
    
  • 将代码编辑器和echarts渲染结合

    实现逻辑:通过监听编辑器的组件的change事件来刷新echarts图,用编辑器里面的内容使用new Function(code)方式实现js动态的代码执行并获取返回值,也就是echarts的option属性,然后通过option的值进行echarts渲染,再通过通过定时的方式进行echarts的大小重绘。

    <template>
      <div id="codeEditor">
        <div class="code-box">
          <JsMonacoEditor v-model="code" @change="changeCode" />
        </div>
        <div class="view-box">
          <el-button type="primary" size="small" @click="refreshChart">运行/刷新</el-button>
          <div ref="chart" class="chart" />
        </div>
      </div>
    </template>
    
    <script>
    import JsMonacoEditor from '@/businessComponents/jsMonacoEditor'
    
    let timer = null
    /*
    * @Description: 代码编辑器
    * @Author: linmt
    * @Date: @Date: 2022-09-11 09:01:31
    */
    export default {
      name: 'CodeEditor',
      components: {
        JsMonacoEditor
      },
      props: {
        echartDemoData: {
          type: Object,
          default: null
        }
      },
      data() {
        return {
          code: 'const option = {};',
          chart: null
        }
      },
      computed: {
    
      },
      watch: {
    
      },
      created() {
        if (this.echartDemoData) {
          this.code = this.echartDemoData.code
        }
      },
      mounted() {
        this.refreshChart()
      },
      beforeDestroy() {
        if (timer) window.clearInterval(timer)
      },
      methods: {
        changeCode() {
          this.refreshChart()
        },
        refreshChart() {
          let _option = null
          try {
            const funCode = new Function(`option=null;${this.code};return option;`)
            _option = funCode()
          } catch (e) {
            console.error(e)
          }
    
          if (!_option) {
            this.$message.error('代码存在问题')
            if (this.chart) {
              this.chart.clear()
            }
            return
          }
    
          if (_option) {
            if (!this.chart) {
              this.chart = window.echarts.init(this.$refs.chart)
            } else {
              this.chart.clear()
            }
    
            // 通过定时的方式进行echarts的大小重绘
            if (timer) window.clearInterval(timer)
            timer = setInterval(() => {
              if (this.chart) {
                this.chart.resize()
              }
            }, 200)
    
            this.chart.setOption(_option, true)
          }
        }
      }
    }
    
    </script>
    <style lang='scss' scoped>
    #codeEditor{
      height: 100%;
      width: 100%;
      display: flex;
      .code-box{
        width: 50%;
        height: 100%;
      }
      .view-box{
        width: 50%;
        height: 100%;
        padding-left: 10px;
        .chart{
          margin-top: 20px;
          height: calc(100% - 80px);
          width: 100%;
        }
      }
    }
    </style>
    

原文地址:http://www.cnblogs.com/linmt/p/16881332.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性