Use el formato CodeMirror en Vue para mostrar el número de línea y el código incorrectos detrás

El proyecto necesita mostrar y editar archivos Json en línea, por lo que necesitamos encontrar un editor de código, porque nuestro proyecto usa directamente la plantilla vueAdmin-template, y el editor json también se toma directamente del proyecto vue-element-admin. .

Artículo reimpreso: https://www.cnblogs.com/wenruo/p/8274958.html

Problemas de encuentro

primera pregunta

Una página tiene múltiples páginas de pestañas, y la visualización de json no está en la primera página de pestañas, luego vaya a la página y haga clic en la página de pestañas donde se encuentra el json... um... el valor predeterminado no se muestra... lo raro es que
al hacer click salian los datos...

segunda pregunta

La visualización del número de línea está desalineada... se vuelve normal cuando el número de línea aumenta a 10 líneas...

analizar

Se sospecha que cuando la página se representa por primera vez, el editor no puede calcular correctamente las propiedades de visualización, como el ancho y el alto, y cuando cambia el clic o el número de filas, se activa una actualización para que la visualización vuelva a ser normal.

Así que encuentre la función de actualización de codemirror, cuando se cambia la pestaña, active manualmente la actualización.

solución

1. Actualización manual

Agregar una función al componente

methods: {
    
    
    refresh() {
    
    
        this.jsonEditor && this.jsonEditor.refresh();
    }
},
需要刷新时去触发该函数。

this.$nextTick(() => {
    
    
    this.$refs.jsonEditor.refresh();
});
2. Agregue el elemento de configuración autoRefresh: verdadero

Sin embargo, la prueba profesional solo puede desencadenar una actualización automática de esta manera. Si aún encuentra problemas, debería considerar la actualización manual.

Código completo (se usan dos soluciones en el código al mismo tiempo, todas comentadas pueden reproducir el error):

<!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>

Otros:
tenga en cuenta que todos los temas, complementos y modos utilizados deben importarse por separado, y la configuración tendrá efecto solo después de la importación

documentación de codemirror https://codemirror.net/doc/manual.html

Finalmente, poner mi propia configuración en el proyecto.

<template>
    <div class="json-editor">
        <textarea ref="textarea"></textarea>
    </div>
</template>
<script>
    import CodeMirror from 'codemirror';
    import 'script-loader!jsonlint';
    import 'codemirror/addon/lint/lint.css';
    import 'codemirror/addon/lint/lint.js';
    import 'codemirror/addon/lint/json-lint';
    import 'codemirror/mode/javascript/javascript';
    import 'codemirror/addon/display/autorefresh';
    import 'codemirror/lib/codemirror.css';
    import 'codemirror/addon/edit/matchbrackets';
    import 'codemirror/addon/fold/foldcode.js';
    import 'codemirror/addon/fold/foldgutter.js';
    import 'codemirror/addon/fold/brace-fold.js';
    import 'codemirror/addon/fold/foldgutter.css';

    export default {
      
      
        name: 'index',
        data() {
      
      
            return {
      
      
                jsonEditor: null
            }
        },
        props: {
      
      
            value: String,
            input: Function
        },
        watch: {
      
      
            // 监听 value 的变化
            value(value) {
      
      
                const editorValue = this.jsonEditor.getValue();
                if (value !== editorValue) {
      
      
                    this.setValue(value);
                }
            }
        },
        mounted() {
      
      
            this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
      
      
                lineNumbers: true,
                mode: 'application/json',
                foldGutter: true,
                gutters: ['CodeMirror-lint-markers', 'CodeMirror-foldgutter'],
                lint: true,
                autoRefresh: true, // 自动触发刷新
                tabSize: 4,
                matchBrackets: true,
                indentUnit: 4
            });
            // 将json文件格式化显示
            this.setValue(this.value);
            // 当输入框内容发生变化 更新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()
            },
            setValue(value) {
      
      
                try {
      
      
                    let newVal = JSON.stringify(JSON.parse(value), null, 4);
                    this.jsonEditor.setValue(newVal);
                } catch (e) {
      
      
                    this.jsonEditor.setValue(value);
                }
            },
            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();
            },
        }
    }
</script>

<style scoped>

</style>

Supongo que te gusta

Origin blog.csdn.net/weixin_52755319/article/details/124825667
Recomendado
Clasificación