程序员用到IDE
次数比较频繁,比如vscode
、idea
等,这些都是市场上比较流行的代码编辑器,拥有非常全面的功能。但是有时候在项目开发上也会用到代码编辑器,比如复杂的Array
输入,或者需要用到用户交互的代码逻辑,或者需要用到json、yaml格式文件时的校验等等。本来也不了解,只是接收到了项目需求,于是开始慢慢了解,以下为一点点实践,不足之处敬请指出
官网链接
栗子
vue2和vue3有专门的版本
vue2使用4/5以下的版本,
vue3可使用6的版本
故不能使用
yarn add codemirror
他会安装最新的版本6
如果系统vue的版本为2,故使用yarn add codemirror@4
codemirror
是基于javascript
开发,所以需要引入很多开发所需的js
、css
文件
vue-codemirror
是一个vue
组件,按照组件的方式引入、注册即可
import { codemirror } from "vue-codemirror";
// require styles
import "codemirror/addon/fold/brace-fold";
import "codemirror/addon/fold/foldcode";
import "codemirror/addon/fold/foldgutter";
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/lib/codemirror.css";
import "codemirror/mode/javascript/javascript";
// JSON错误检查
import "codemirror/addon/lint/lint.css";
import "codemirror/addon/lint/lint.js";
// 需要依赖全局的jsonlint,不是很优雅
import "codemirror/addon/lint/json-lint.js";
import "codemirror/addon/lint/yaml-lint.js";
//及时自动更新,配置里面也需要设置autoRefresh为true
import "codemirror/addon/display/autorefresh";
// 支持括号自动匹配
import "codemirror/addon/edit/closebrackets.js";
import "codemirror/addon/edit/matchbrackets.js";
// 引入dark主题
import "codemirror/theme/duotone-dark.css";
// 全屏
import "codemirror/addon/display/fullscreen";
// 引入jsonlint
import jsonlint from "jsonlint-mod";
beforeCreate() {
window.jsonlint = jsonlint;
},
cmOptions: {
mode: "application/json", // 语言及语法模式
theme: "idea", // 主题
autoRefresh: true, // 自动刷新
line: true, // 显示函数
lint: true, // 校验
matchBrackets: true, // 括号匹配显示
autoCloseBrackets: true, // 输入和退格时成对
indentUnit: 2, // 缩进单位,默认2
lineWrapping: true, // 软换行
tabSize: 4, // tab宽度
lineNumbers: true, // 显示行数
foldGutter: true,
smartIndent: true, // 智能缩进
gutters: [
"CodeMirror-linenumbers",
"CodeMirror-foldgutter",
"CodeMirror-lint-markers", // 实现语法报错
],
},
一般code
传入时是Array
, Object
, String
,所以需要将他进行json.stringify
序列化,用2个空
格作为缩进
code: {
handler(newVal) {
const str = newVal || [];
this.newCode = JSON.stringify(str, null, 2);
},
immediate: true,
},
this.$refs.cm.codemirror.setSize("100%", "auto");
readOnly
一般存在三种属性:
true
:不可编辑,不可复制false
:可编辑,可复制nocursor
:不可编辑,可复制this.$refs.cm.codemirror.setOption("readOnly", "nocursor");
很多时候,需要codemirror
沾满剩余的高度,有时候屏幕会涉及大小屏切换,故涉及到元素监听,高度自动计算功能,主要使用ResizeObserver
属性进行观察元素大小是否改变,主要代码如下:
created() {
this.$nextTick(() => {
this.onResizeObserver();
});
},
beforeDestroy() {
const ele = document.querySelector(".v-form");
if (ele) {
// 取消对class为v-form的元素进行观察
this.resizeObserver.unobserve(ele);
}
},
methods: {
onResizeObserver() {
const _this = this;
this.resizeObserver = new ResizeObserver((entries) => {
_this.setHeight(_this.reHeight);
});
// 在表单的情况下,resize,自动计算高度
const ele = document.querySelector(".v-form");
if (ele) {
// 对class为v-form的元素进行观察
this.resizeObserver.observe(ele);
}
},
// 高度计算
setHeight(fn) {
if (this.readOnly) {
return;
}
const panelHeight = document
.querySelectorAll(".panel")[0]
.getBoundingClientRect().height;
const headerHeight = document
.querySelectorAll(".panel-header")[1]
.getBoundingClientRect().height;
const content = document.querySelector(".content");
const fontSize = +getComputedStyle(window.document.documentElement)[
"font-size"
].replace("px", "");
const num = 1.8 * fontSize * 3;
const contentHeight = content.getBoundingClientRect().height - num;
let height = contentHeight - panelHeight - headerHeight - fn();
// console.log('height', height)
if (height < 300) {
height = 300;
}
this.$nextTick(() => {
this.$refs.cm.codemirror.setSize("100%", height);
});
},
},
https://codesandbox.io/s/vue-codemirror-json-editor-forked-yvf11d?file=/src/components/JsonEditor.vue:185-229
大概实现了以下几个功能:
json
校验codemirror
占满剩余高度readOnly
大概包括以下几种原因:
import
语句导入组件时from
后面的路径写错import
声明的不一致components
写错导致无法使用/
反斜杠结尾// 引入自动刷新文件
**import 'codemirror/addon/display/autorefresh'**
cmOptions: {
// 语言及语法模式
mode: 'application/json',
// 主题
theme: 'duotone-dark',
**autoRefresh: true, // 自动刷新**
// 显示函数
line: true,
lint: true, // 校验
matchBrackets: true, // 括号匹配显示
autoCloseBrackets: true, // 输入和退格时成对
indentUnit: 2, // 缩进单位,默认2
// 软换行
lineWrapping: true,
// tab宽度
tabSize: 4,
lineNumbers: true,
lineWrapping: true,
foldGutter: true,
gutters: [
'CodeMirror-linenumbers',
'CodeMirror-foldgutter',
'CodeMirror-lint-markers', // 实现语法报错
],
},
https://blog.51cto.com/u_15703146/5716514
https://www.cnblogs.com/proboxdu/p/16137537.html
https://codesandbox.io/s/vue-codemirror-json-editor-forked-yvf11d
https://codemirror.net/