一、背景
由于项目需要用到 json
编辑功能,尝试使用过 v-jsoneditor
, vue-json-editor
和 vue-codemirror
, 使用都不尽人意,一番尝试之后,用 codemirror
成功满足需求,小记录一下。
二、codemirror介绍
CodeMirror 是使用 JavaScript
为浏览器实现的多功能文本编辑器。它专门用于编辑代码,并具有实现更高级编辑功能的多种语言模式 (language mode)和附加组件(addon)。CodeMirror
具有丰富的 API 和 CSS 主题系统,方便用户为其应用程序作定制化,并且易于扩展。本文主要聚焦于在 vue
工程中 json
的编辑功能。
三、codemirror使用
1. 所需依赖
npm install --save codemirror
npm install --save jsonlint
没有使用 vue-codemirror
,直接在 vue
中使用 codemirror
。
此外,需要安装一个开发依赖 script-loader
,方便引入 jsonlint
。
npm install --save-dev script-loader
我安装的版本如下:
"codemirror": "^5.59.2",
"jsonlint": "^1.6.3",
"script-loader": "^0.7.2",
2. JsonEditor 组件
直接封装好 JsonEditor
组件,在 src/components
新建 JsonEditor.vue
文件,如下
直接上代码
<template>
<div class="json-editor">
<textarea ref="textarea"></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'
export default {
name: 'JsonEditor',
props: {
json: {
type: String,
default: '',
},
},
data() {
return {
jsonEditor: null,
}
},
watch: {
json(val) {
const editorValue = this.jsonEditor.getValue()
if (val !== editorValue) {
this.jsonEditor.setValue(this.json)
}
},
},
mounted() {
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
mode: 'application/json',
theme: 'rubyblue', // 主日样式
lint: true,
tabSize: 2,
smartIndent: true, // 是否智能缩进
styleActiveLine: true, // 当前行高亮
lineNumbers: true, // 显示行号
gutters: ['CodeMirror-lint-markers'],
lineWrapping: true, // 自动换行
matchBrackets: true, // 括号匹配显示
autoCloseBrackets: true, // 输入和退格时成对
autoRefresh: true, // 自动刷新
})
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 scoped>
.json-editor {
height: 100%;
position: relative;
}
.json-editor >>> .CodeMirror {
height: auto;
min-height: 250px;
}
.json-editor >>> .CodeMirror-scroll {
min-height: 250px;
}
.json-editor >>> .cm-s-rubyblue span.cm-string {
color: #f08047;
}
</style>
其中,需要注意的是代码主题样式可以根据自己的喜好去官网选择,并引入相应的 css
文件即可,我选择的是 rubyblue
这个主题
还有个坑就是当编辑器隐藏和显示时,容易出现样式错乱
解决方法是将 autoRefresh
设为 true
,并且加上 refresh
函数,每次打开编辑器时刷新一下编辑器,具体可以参考一下这篇文章 https://www.cnblogs.com/wenru...。
3. 使用
使用起来很方便,需要的地方直接引入 JsonEditor
组件,直接上代码
<template>
<div>
<json-editor
ref="jsonEditor"
:json="json"
@change="handleJsonChange"
/>
</div>
</template>
<script>
import JsonEditor from '@/components/JsonEditor'
export default {
components: {
JsonEditor,
},
data() {
json: '',
},
mounted() {
// 刷新jsonEditor
this.$nextTick(() => {
this.$refs.jsonEditor.refresh()
})
},
methods: {
handleJsonChange(val) {
if (this.json !== val) {
this.json = val
}
},
}
}
</script>
这样就可以愉快地编写 json
代码了
也会提示格式错误。如果输入的 json
是需要提交的,可以通过 JSON.parse
来进行校验,阻止提交
// ...
// 判断表达式是否符合要求
if (this.json) {
try {
JSON.parse(this.json)
} catch (e) {
this.$message.warning('请输入正确的 json')
return
}
}
// ...
CodeMirror
功能非常强大,如代码自动补全、代码折叠、绑定 vim
和 设置快捷键等功能,可以官网上查找,本文只记录了笔者所用到的一些简单的功能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。