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

項目須要在線展現和編輯Json文件,因此須要找一個代碼編輯器,由於咱們的項目直接使用的 vueAdmin-template 這個模板,json編輯器也是直接從 vue-element-admin 項目扒下來的……javascript

遇到問題

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

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

第二個問題vue

行數顯示錯位……當行數增長爲10行時即變爲正常……java

 

分析

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

因此找到 codemirror 的刷新函數,當 tab 切換的時候,手動觸發刷新便可。github

在組件中新增一個函數 ajax

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

須要刷新時去觸發該函數。npm

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

 

 

解決方案

增長配置項  autoRefresh: true json

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

 

完整代碼:

<!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="hanldeReset">重置</button>
        <button @click="hanldeSave">保存</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: {
            hanldeReset() {
                this.jsonData = '{"key":"value"}';
            },
            hanldeSave() {
                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 

相關文章
相關標籤/搜索