Vue项目中使用codemirror编辑器

·  阅读 5657
Vue项目中使用codemirror编辑器

最近尝试了几个嵌入到项目的编辑器,有monaco,json-editor,然后就是这个codemirror了。为什么要用?那必须是因为项目需求呀。

纪念成功嵌入,在此做一个小小的记录。

使用的内容比较初级,更多的options依旧还是看官网的介绍吧(😀😀😀😀😀😀)

codemirror:代码编辑器,为了编辑json而引入的

下载依赖

// 这玩意就是本体啦
npm install --save codemirror

// 然后这玩意,是用来处理json的
npm install --save jsonlint

// 最后就是这玩意,开发依赖,为的是方便引入jsonlint
npm install --save-dev script-loader
复制代码

考虑到其他地方也可能要用到,那就简单粗暴的封装起来吧

<template>
    <div class="json-editor">
        <textarea ref="textarea" />
    </div>
</template>

<script>
import CodeMirror from "codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/mode/javascript/javascript"; // 代码高亮必须引入

// 代码错误检查
// eslint-disable-next-line import/no-webpack-loader-syntax
require("script-loader!jsonlint");
import "codemirror/addon/lint/lint.css";
import "codemirror/addon/lint/lint";
import "codemirror/addon/lint/json-lint";

// 主题样式(我直接用了纯白色的,看着比较舒服)
import "codemirror/theme/rubyblue.css";
// 括号显示匹配
import "codemirror/addon/edit/matchbrackets";
import "codemirror/addon/selection/active-line";
// 括号、引号编辑和删除时成对出现
import "codemirror/addon/edit/closebrackets";
// 折叠代码要用到一些玩意
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/fold/foldgutter";
import "codemirror/addon/fold/xml-fold";
import "codemirror/addon/fold/foldcode";
import "codemirror/addon/fold/brace-fold";
import "codemirror/addon/fold/indent-fold.js";
import "codemirror/addon/fold/markdown-fold.js";
import "codemirror/addon/fold/comment-fold.js";

export default {
    name: "CodeMirror",
    components: {},
    props: {
        jsonCode: {
            type: String,
            default: "",
        },
        readonly: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
            jsonEditor: "",
        };
    },
    watch: {
        jsonCode(newVal) {
            const editorValue = this.jsonEditor.getValue();
            if (newVal !== editorValue) {
                this.jsonEditor.setValue(
                    // 这里是json格式化
                    JSON.stringify(JSON.parse(this.jsonCode), null, 2)
                );
                setTimeout(() => {
                    this.jsonEditor.refresh();
                }, 1);
            }
        },
        immediate: true,
        deep: true,
    },
    mounted() {
        this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
            mode: "application/json",
            theme: "base16-light", // 主题样式
            lint: true,
            tabSize: 2,
            smartIndent: true, // 是否智能缩进
            styleActiveLine: true, // 当前行高亮
            lineNumbers: true, // 显示行号
            gutters: [
                "CodeMirror-linenumbers",
                "CodeMirror-foldgutter",
                "CodeMirror-lint-markers",
            ],
            lineWrapping: true, // 自动换行
            matchBrackets: true, // 括号匹配显示
            autoCloseBrackets: true, // 输入和退格时成对
            readOnly: this.readonly, // 只读
            foldGutter: true,
        });
        // 这里是json格式化
        this.jsonEditor.setValue(JSON.stringify(JSON.parse(this.jsonCode)));
        this.jsonEditor.on("change", cm => {
            this.$emit("change", cm.getValue());
        });
    },
    methods: {
        // 这玩意就是为了刷新编辑器的
        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>
.json-editor {
    height: 100%;
    position: relative;
}
/* 高度自适应 */
.json-editor .CodeMirror {
    height: auto;
}
.json-editor .CodeMirror-scroll {
    height: auto;
    overflow-y: hidden;
    overflow-x: auto;
}

.CodeMirror-foldgutter-folded.CodeMirror-guttermarker-subtle {
    color: black !important;
    font-size: 14px;
}
.CodeMirror-foldgutter-open:after {
    color: black !important;
    font-size: 14px;
}
.json-editor .cm-string {
    color: coral !important;
}
</style>

复制代码

最后就是在页面中的使用了

<template>
    <div>
        <el-form :model="form" label-width="120px">
            <el-form-item label="New Version:">
                <el-input size="mini" v-model="form.version" readonly />
            </el-form-item>
            <el-form-item label="Json:">
                <div class="code-mirror-box">
                    <code-mirror
                        ref="jsonEditor"
                        :json-code="form.jsonCode"
                        :readonly="readonly"
                        @change="handleJsonChange"
                    />
                </div>
            </el-form-item>
            <el-form-item>
                <el-button> Cancle </el-button>
                <el-button> Submit </el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
import CodeMirror from "../../component/json_com/codemirror.vue";
export default {
    components: {
        CodeMirror,
    },
    props: {},
    data() {
        return {
            form: {
                jsonCode: "{}",
                version: null,
            },
            readonly: false,
        };
    },
    created() {
        ...
    },
    mounted() {
        // 刷新jsonEditor
        this.$nextTick(() => {
            this.$refs.jsonEditor.refresh();
        });
    },
    methods: {
        handleJsonChange(val) {
            if (this.jsonCode !== val) {
                this.jsonCode = val;
            }
        },
        getData(_id) {
            this.apiGet("...", {
                _id,
            }).then(res => {
                if (res.code === 0) {
                    this.form.version = res.body.config.version;
                    this.form.jsonCode = JSON.stringify(res.body.config);
                } else {
                    console.error(res.message, "version config detail data");
                    this.$message.error(res.message);
                }
            });
        },
        submit() {
            ...
        },
    },
};
</script>

<style scoped>
.code-mirror-box {
    height: 580px;
    overflow-y: scroll;
    overflow-x: auto;
}
</style>

复制代码

蜜汁bug

1.使用时遇到的一个问题,就是编辑器数据的渲染,有点像是懒加载的感觉,然后到最下面的数据,会出现加载不出来的情况,如图所示

image.png

讲道理,我真的不用知道这玩意为什么会这样,然后我的解决办法就是,在页面中,把这一部分包裹在一个div里面,然后给这个div设置高度,不让滚动条显示出来,这样就解决了这个问题。

各位大佬要是遇到过同样的问题,并且成功解决,还望指点一下小弟,多谢!!

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改