在Vue中使用CodeMirror 格式顯示錯誤 行數錯亂 & 代碼隱藏


項目需要在線展示和編輯Json文件,所以需要找一個代碼編輯器,因為我們的項目直接使用的 vueAdmin-template 這個模板,json編輯器也是直接從 vue-element-admin 項目扒下來的……

遇到問題

第一個問題,一個頁面有多個tab頁,而json顯示不在第一個tab頁中,那么跳轉到頁面再點擊json所在tab頁……

嗯……默認顯示不出來……奇怪的事情是,當你點擊一下,數據就出來了……

第二個問題

行數顯示錯位……當行數增加為10行時即變為正常……

 

分析

懷疑是由於當頁面第一次渲染時,編輯器沒有能正確的計算寬高等展示屬性,當點擊或者行數變化時觸發了刷新所以顯示變為正常。

所以找到 codemirror 的刷新函數,當 tab 切換的時候,手動觸發刷新即可。

 

解決方案

1、手動刷新

在組件中新增一個函數 

methods: {
    refresh() {
        this.jsonEditor && this.jsonEditor.refresh(); } },

需要刷新時去觸發該函數。

this.$nextTick(() => {
    this.$refs.jsonEditor.refresh(); });

 

2、增加配置項  autoRefresh: true 

但是親測這樣只能觸發一次自動更新,如果還是遇到問題的話還是要考慮手動刷新。

 

完整代碼(代碼里同時使用了兩種解決方案,全部注釋掉可以復現bug):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>test vue json editor</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jsonlint/1.6.0/jsonlint.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/addon/lint/lint.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/addon/lint/json-lint.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/mode/javascript/javascript.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/addon/display/autorefresh.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/theme/darcula.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/addon/lint/lint.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.css" />
</head>
<body>
<div id="app">
  {{ title }}
  <button @click="handleVisibleChange">顯示/隱藏</button>
  <div v-show="show">
    <json-editor ref="jsonEditor" v-model="jsonData"></json-editor>
    <button @click="handleReset">重置</button>
    <button @click="handleSave">保存</button>
  </div>
</div>

<script>
  // 注冊編輯器組件
  Vue.component('json-editor', {
    template: `<div class="json-editor"><textarea ref="textarea"></textarea></div>`,
    data() {
      return {
        jsonEditor: null
      }
    },
    props: {
      value: String,
      input: Function
    },
    watch: {
      // 監聽 value 的變化
      value(value) {
        const editorValue = this.jsonEditor.getValue();
        if (value !== editorValue) {
          this.jsonEditor.setValue(JSON.stringify(JSON.parse(value), null, 2));
        }
      }
    },
    mounted() {
      this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
        lineNumbers: true,
        mode: 'application/json',
        gutters: ['CodeMirror-lint-markers'],
        theme: 'darcula',
        lint: true,
        autoRefresh: true // 自動觸發刷新
      });
      // 將json文件格式化顯示
      this.jsonEditor.setValue(JSON.stringify(JSON.parse(this.value), null, 2));
      // 當輸入框內容發生變化 更新value值
      this.jsonEditor.on('change', cm => {
        this.handleInput(cm);
        this.$emit('changed', cm.getValue());
        this.$emit('input', cm.getValue());
      });
    },
    methods: {
      getValue() {
        return this.jsonEditor.getValue()
      },
      handleInput(e) {
        if (this.changeFn) {
          this.changeFn(e.getValue())
        }
      },
      refresh() {
        /*
         * refresh: Fires when the editor is refreshed or resized.
         *          Mostly useful to invalidate cached values that depend on the editor or character size.
         */
        this.jsonEditor && this.jsonEditor.refresh();
      }
    }
  });

  var app = new Vue({
    el: '#app',
    data: {
      title: 'JSON 編輯器',
      jsonData: '{"key":"value"}',
      show: false
    },
    methods: {
      handleReset() {
        this.jsonData = '{"key":"value"}';
      },
      handleSave() {
        alert(this.jsonData);
      },
      // 當切換視圖為顯示json編輯器時 手動刷新
      handleVisibleChange() {
        if (this.show = !this.show) {
          this.$nextTick(() => {
            this.$refs.jsonEditor.refresh(); // 手動觸發刷新
          });
        }
      }
    }
  });
</script>
</body>
</html>

 

其他:

注意所有用到的 theme,addon,mode 都需要單獨引入,引入之后配置才會生效

codemirror 文檔 https://codemirror.net/doc/manual.html 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM