codemirror封装
2024-01-01 13:44:04
<template>
<div class="in-coder-panel">
<textarea ref="codeform" v-model="code" class="codemirror"></textarea>
</div>
</template>
<script>
import { watch, onMounted, onBeforeUnmount, ref } from "vue";
// 引入全局实例
import _CodeMirror from "codemirror";
// 核心样式
import "codemirror/lib/codemirror.css";
import "codemirror/addon/hint/show-hint.css";
// 引入主题后还需要在 options 中指定主题才会生效
const themList = [];
const requireModules = require.context("codemirror/theme/", false, /.css$/);
requireModules.keys().forEach((value) => {
const newValue = value.replace(/^.\//, "").replace(/.css$/, "");
themList.push(newValue);
});
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
// import "codemirror/addon/selection/active-line";
// import "codemirror/addon/display/aoturefresh";
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/css/css.js";
import "codemirror/mode/xml/xml.js";
import "codemirror/mode/clike/clike.js";
import "codemirror/mode/markdown/markdown.js";
import "codemirror/mode/python/python.js";
import "codemirror/mode/r/r.js";
import "codemirror/mode/shell/shell.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/mode/swift/swift.js";
import "codemirror/mode/vue/vue.js";
import "codemirror/mode/yaml/yaml.js";
//import "codemirror/mode/yaml-frontmatter/yaml-frontmatter.js";
require("codemirror/addon/edit/matchbrackets");
require("codemirror/addon/selection/active-line");
require("codemirror/addon/lint/yaml-lint");
require("codemirror/addon/hint/show-hint");
require("codemirror/addon/hint/anyword-hint");
require("codemirror/addon/display/autorefresh");
// 尝试获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror;
export default {
emits: ["onUpdate:value"],
props: {
id: {
type: Number,
default: 0,
},
// 外部传入的内容,用于实现双向绑定
value: {
type: String,
default: "",
},
readonly: {
type: Boolean,
default: false,
},
// 可用事件'change', 'blur'等等;具体参考codemirror文档
eventType: {
type: String,
default: "blur",
},
// 外部传入的语法类型
language: {
type: String,
default: "x-yaml",
},
// 编辑器主题色
theme: {
type: String,
default: "mbo",
},
},
setup(props, { emit }) {
const codeform = ref(null);
const code = ref(props.value);
let editor = null;
let options = {};
let modes = {};
// 默认配置
options = {
mode: "text/x-yaml",
tabSize: 1, // 缩进格式
indentWithTabs: true,
smartIndent: true,
lineWrapping: true,
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
autoRefresh: true,
theme: props.theme ? props.theme : "mbo",
lint: false,
lineWiseCopyCut:false,
readOnly: props.readonly === false ? false : "nocursor", // true: 不可编辑 false: 可编辑 'nocursor' 失焦,不可编辑
extraKeys: { Ctrl: "autocomplete" }, //自定义快捷键
hintOptions: {},
// matchBrackets: true,
// foldGutter: true,
// gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
};
modes = {
css: "text/css",
javascript: "text/javascript",
"xml/html": "text/html",
yaml: "text/x-yaml",
java: "text/x-java",
"objective-c": "text/x-objectivec",
python: "text/x-python",
r: "text/x-rsrc",
shell: "text/x-sh",
sql: "text/x-sql",
swift: "text/x-swift",
vue: "text/x-vue",
markdown: "text/markdown",
};
// 初始化
function initialize() {
if (editor) {
editor.toTextArea();
}
if (props.language) {
let lan = props.language.toLowerCase();
let modeObj = modes[lan] ? modes[lan] : "";
options.mode = modeObj ? modeObj : options.mode;
}
editor = CodeMirror.fromTextArea(codeform.value, options);
/*editor.on("keyup", function () {
editor.showHint();
});*/
// 支持双向绑定
editor.on(props.eventType, (coder) => {
if (emit) {
emit("onUpdate:value", coder.getValue());
}
});
}
// 动态引入语法高亮库
function themeImport() {
return new Promise((resolve) => {
themList.forEach((value) => {
if (props.theme === value) {
import(`codemirror/theme/${props.theme}.css`);
resolve();
}
});
});
}
watch(
() => props.id,
() => {
themeImport().then(() => {
initialize();
});
}
);
watch(
() => props.value,
(newProps) => {
code.value = editor ? editor.setValue(newProps) : "";
editor.refresh();
}
);
onMounted(() => {
themeImport().then(() => {
initialize();
});
});
onBeforeUnmount(() => {
editor.off(props.eventType);
});
return {
code,
codeform,
initialize,
};
},
};
</script>
文章来源:https://blog.csdn.net/qq_35434878/article/details/135323830
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!