codemirror构建一个xml编辑器

定义一个html使用形式的Vue组件:

Vue.component("v-codemirror-editor", {
    data() {
        return {
            editor: null,
            style: {},
            max: false,
            json: this.value,
            internalChange: false,
            defaultOptions: {
                tabSize: 4,
                mode: "text/x-groovy",   //默认groovy
                lineNumbers: true,       //显示行号
                lineWrapping: true,      //代码折叠
                styleActiveLine: true,   // 当前行背景高亮
                indentUnit: 4,           // 缩进单位为4
                matchBrackets: true,     //括号匹配
                smartIndent: true,       // 自动缩进
                autofocus: true,         // 自动焦点
                autoCloseBrackets: true  // 自动补全括号
            }
        }
    },
    props: {
        options: {
            type: Object,
            default: () => {
                return {
                    mode: "text/x-groovy"
                }
            }
        },
        modes: {
            type: Array,
            default: function() {
                return ["text/x-groovy", "text/x-java", "text/x-scala", "text/x-go", "text/javascript", "application/xml"];
            }
        },
        value: {
            type: String,
            default: ''
        },
        height: {
            type: String
        },
        schema: null,
        autosize:  {
            type: Object,
            default: () => {
                return {
                    maxHeight: 500,
                    minHeight: 200
                }
            }
        }
    },
    methods: {
        onChange() {
            try {
                let json = this.editor.get();
                if (this.editor) {
                    this.internalChange = true;
                    this.json = json;
                    this.$emit("code-change", json);
                    this.$nextTick(() => {
                        this.internalChange = false
                    })
                }
            } catch (err) {
                this.$emit("code-error", err);
            }
        },
        initView() {
            const self = this;
            const _options = Object.assign(this.defaultOptions, this.options);
            console.log("CodeMirror options: ", _options)
            this.editor = CodeMirror.fromTextArea(this.$el.querySelector('textarea'), _options)
            this.editor.setValue(this.value)
            this.editor.on('change', function(cm) {
                if (!!self.$emit) {
                    self.$emit('code-change', cm.getValue());
                    self.$emit('input', cm.getValue());
                }
            });
            this.editor.on('keyup', function(cm, event) {
                //console.log(event.keyCode)
                if(!cm.state.completionActive && ((event.keyCode >= 65 && event.keyCode <= 90)
                    || event.keyCode === 52 || event.keyCode === 219 || event.keyCode === 190
                    || event.keyCode === 188 || event.keyCode === 57) ) {
                    CodeMirror.commands.autocomplete(cm, null, {completeSingle:false})
                }
            });
            self.$emit('code-init', this, this.editor, this.editor.getValue());
        },
        refresh() {
            this.$nextTick(() => {
                this.editor.refresh()
            })
        },
        destroyView() {
            if (this.editor) {
                // garbage cleanup
                const element = this.editor.doc.cm.getWrapperElement()
                element && element.remove && element.remove();
                this.editor = null;
            }
        },
        handlerCodeChange(newVal) {
            var editorValue = this.editor.getValue();
            if (newVal !== editorValue) {
                var scrollInfo = this.editor.getScrollInfo();
                this.editor.setValue(newVal)
                this.editor.scrollTo(scrollInfo.left, scrollInfo.top)
            }
        },
        async setEditor(value) {
            if (this.editor) {
                //this.json = value;
                this.editor.setValue(value);
            }
        }
    },
    watch: {
        options: {
            deep: true,
            handler(options) {
                for (const key in options) {
                    this.editor.setOption(key, options[key])
                }
            }
        },
        value(newVal) {
            this.handlerCodeChange(newVal);
        },
        // value: {
        //     immediate: true,
        //     async handler(val) {
        //         //console.log("val:" + JSON.stringify(val));
        //         if (!this.internalChange) {
        //             //await this.setEditor(val);
        //             this.setEditor(val);
        //         }
        //     },
        //     deep: true
        // },
        max(value) {
            this.$nextTick(() => {
                this.initView()
            })
        }
    },
    mounted() {
        this.initView()
    },
    beforeDestroy() {
        this.destroyView()
    },
    computed: {
        getHeight() {
            if (!this.max) {
                console.log(this)
                console.log(this.$el)
                console.log("this.height: ", typeof this.$el)
                console.log("this.height: ", typeof this)
                if(this.$el) {
                    console.log("this.offsetWidth: ", this.$el.offsetWidth)
                }
                //console.log("autosize:" + JSON.stringify(this.autosize));
                let h = this.height;
                let maxHeight = this.autosize.maxHeight;
                let minHeight = this.autosize.minHeight;
                if (this.editor) {

                    let json = JSON.stringify(this.editor.getValue());

                    // console.log("jsonlength : ", json.length);
                    // console.log("json : ", json);

                    let ch = 0;
                    if(undefined !== json && null !== json && this.$el) {
                        ch = (json.length / this.$el.offsetWidth) * 140 + 50;
                        if(json.indexOf('\n') > -1) {
                            console.log("json split: ", json.split('\n').length);
                            ch = ch + json.split('\n').length * 80;
                        }
                    }

                    if(maxHeight && ch > maxHeight) {
                        ch = maxHeight;
                    }
                    if(minHeight && ch < minHeight) {
                        ch = minHeight;
                    }
                    h = ch + "px";
                    console.log("getHeight:" + h);
                }
                return {
                    height: h
                }
            }
            return {}
        }
    },
    template: '  
' + ' ' + '
' });

页面使用:




    
    
    
    
    
    
    
    

    
    
    
    


选项1 选项2 选项3 选项4-1 选项1 选项2 选项3 选项4-1 选项1 选项2 选项3 选项4-1 查看 新增 删除 王小虎
解决方案
履约拓扑
保存 取消 保存 取消
{{template "router" .}}

你可能感兴趣的:(codemirror构建一个xml编辑器)