【问题标题】:Vuetify dialog - extremely slow formatting 2.5MB of XML in ACE editorVuetify 对话框 - 在 ACE 编辑器中格式化 2.5MB 的 XML 非常慢
【发布时间】:2021-07-23 05:58:29
【问题描述】:

我有一个 Vue/Vuefify 项目,我正在使用 vkbeutify 库来格式化 XML,然后在 Ace 编辑器中显示它。编辑器在模式对话框(全屏模式)中打开,当 XML 的数量很少时,一切都很好。

我必须解析大约 2.5MB 以上(在 Notepad++ 中格式化时大约 2,500,000 个字符),然后 Ace 变得无法使用(它最终会显示 XML,但需要很长时间)。

我创建了一个带有文本区域和编辑器的简单测试页面,并且格式化和显示速度非常快。该页面与此完全相同:https://www.webtoolkitonline.com/xml-formatter.html(这使用 Ace 和 vkbeautify 来格式化 xml)

我尝试在将 XML 传递给子对话框之前在文本区域中对其进行预格式化,尝试颠覆 Vue 并通过直接获取 DOM 内容来填充 mount() 函数中的编辑器容器。

独立测试页面:

    <!DOCTYPE html>
<html lang="en">
<head>
    <title>ACE in Action</title>
    <style type="text/css" media="screen">#editor {position: absolute;top: 0;right: 0;bottom: 0;left: 0;}</style>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="https://pagecdn.io/lib/ace/1.4.5/ace.js" integrity="sha256-5Xkhn3k/1rbXB+Q/DX/2RuAtaB4dRRyQvMs83prFjpM=" crossorigin="anonymous"></script>
    <script src="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/vkbeautify/vkbeautify.0.99.00.beta.js"></script>
</head>
<body>
<div style="position: relative; width: 100%; height: 500px;">
<div id="editor">
    <tag><inner_tag>sce to aux</inner_tag></tag>
</div>
</div>
<div>
<form>
    <textarea id="xml"><?xml version="1.0" encoding="UTF-8"?><tag><inner_tag>hi</inner_tag></tag></textarea>
    <fieldset><input type="button" id="format" value="Format"></fieldset>
</form>
</div>
<script>
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/cobalt");
    editor.session.setMode("ace/mode/xml");
    $( function() {
        $( "#format").click(
            async function() {
                var content = document.getElementById("xml").value;
                try {
                    editor.setValue(  content  );
                    editor.setValue( vkbeautify.xml( editor.getValue()  ) );
                } catch( err ) {
                    alert( "Your document is invalid" );
                }
            }
        );
    });
</script>
</body>
</html>

Vue 组件:

    <template>
  <div>
    <b>Open In Editor </b>
    <v-btn icon color="transparent" depressed small @click="openInEditor()"><v-icon color="#666666">mdi-pencil</v-icon>
    </v-btn>
    <v-dialog v-model="showAceEditorModal" fullscreen hide-overlay eager>
      <v-card>
        <v-toolbar dark color="primary">
          <v-btn icon dark @click="closeAceEditor">
            <v-icon>mdi-close</v-icon>
          </v-btn>
          <v-toolbar-title>{{title}}</v-toolbar-title>
          <v-card-text v-if="editable===false"> Read Only Mode - you won't be able to edit or save changes</v-card-text>
          <v-spacer></v-spacer>
          <v-toolbar-items>
            <v-btn dark text @click="sendEditsToParent">
              {{ closeLabelTxt }}
            </v-btn>
          </v-toolbar-items>
        </v-toolbar>
        <div :id=editorIdX >
          {{ v }}
        </div>
        <div id="test"></div>
      </v-card>
    </v-dialog>
  </div>
</template>
<script>
import * as ace from '@/assets/js/ace/src-min-noconflict/ace.js';
import * as v from '@/assets/js/ace/vkbeautify.js';
export default {
  name: "AceEditor",
  props:['title', 'editable', 'value', 'originalItem', 'editorIdX'],

  data(){
    return {
      v : "",
      oldItem : this.originalItem,
      showAceEditorModal: false
    }
  },

  computed : {
    closeLabelTxt : function (){
      return this.editable?"Save":"Close Me";
    }
  },
  mounted(){
    this.v = document.getElementById("textArea_0").value
    document.getElementById("test").innerText = document.getElementById("textArea_0").value
  },
  methods:{
    openInEditor(){
      this.editorId = this.editorIdX;
      this.editor = ace.edit(  this.editorIdX  );
      if( this.editable === false ){
        this.editor.setReadOnly( true );
      }

      //  deprecation fix
      this.editor.$blockScrolling = Infinity;
      //  ignore doctype warnings
      const session = this.editor.getSession();
      session.on("changeAnnotation", () => {
        const a = session.getAnnotations();
        const b = a.slice(0).filter( (item) => item.text.indexOf('DOC') == -1 );
        if(a.length > b.length) session.setAnnotations(b);
      });

      //  editor options
      this.options = this.options || {};

      //  opinionated option defaults
      this.options.maxLines = this.options.maxLines || Infinity;
      this.options.printMargin = this.options.printMargin || false;
      this.options.highlightActiveLine = this.options.highlightActiveLine || false;

      //  hide cursor
      if(this.options.cursor === 'none' || this.options.cursor === false){
        this.editor.renderer.$cursorLayer.element.style.display = 'none';
        delete this.options.cursor;
      }

      //  add missing mode and theme paths
      if(this.options.mode && this.options.mode.indexOf('ace/mode/')===-1) {
        this.options.mode = `ace/mode/${this.options.mode}`;
      }
      if(this.options.theme && this.options.theme.indexOf('ace/theme/')===-1) {
        this.options.theme = 'ace/theme/${this.options.theme}';
      }
      this.editor.setOptions(this.options);
      this.showAceEditorModal = true;
    },

    closeAceEditor(){
      this.showAceEditorModal = false;
    },
    sendEditsToParent(){
      if( this.editor.getReadOnly() === false ){
        this.$emit('editedItem', [ {"editedItem": this.editor.getValue() }, {"originalItem":this.oldItem}]);
      }
      this.showAceEditorModal = false
    },
    reformatContent(){
      let x = this.editor.session.getValue();
      this.editor.session.setValue("");
      x = vkbeautify.xml( x );
      this.editor.session.setValue( x );
    }
  }
}
</script>

【问题讨论】:

    标签: xml vue.js vuetify.js ace-editor


    【解决方案1】:

    发生这种情况是因为您通过禁用编辑器的虚拟屏幕优化将maxLines 设置为InfinitymaxLines 适用于小于窗口高度的小型 sn-ps。

    【讨论】:

    • @a 用户,...做到了!之后我遇到了另一个问题:在编辑器配置更改后,在 Vue 模态中,编辑器的容器由于某种原因高度为 0,因此它似乎根本没有加载。容器高度必须解决,但这是小事。现在艾斯在尖叫 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多