这里主要自己使用yaml。
npm install vue-codemirror -D
//yaml转json+json转yaml
npm install yamljs -D
npm install json2yaml -D
原理
1.封装codemirror
组件。
2.页面用watch
监控form表单,将json转yaml更新视图
3.利用emit
编辑内容时调用页面里的yaml转json更新form表单
组件
<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 来实现动态加载对应语法高亮库
// 把对应的 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", "set-form"],
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: "dracula",
},
},
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: 2, // 缩进格式
indentWithTabs: true,
smartIndent: true,
lineWrapping: true,
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
autoRefresh: true,
theme: props.theme ? props.theme : "dracula",
lint: true,
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) {
//同步value
emit("onUpdate:value", coder.getValue());
//更新表单
emit("set-form", 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.setValue(newProps);
}
);
onMounted(() => {
themeImport().then(() => {
initialize();
});
});
onBeforeUnmount(() => {
editor.off(props.eventType);
});
return {
code,
codeform,
initialize,
};
},
};
</script>
页面
<template>
<el-button @click="add"></el-button>
<el-dialog v-model="addVisible" title="创建" width="800px">
<div>
<span>是否编辑模式:</span>
<span class="switch-container">
<el-switch
v-model="modeswitch"
active-text="是"
inactive-text="否"
></el-switch>
</span>
</div>
<el-form
:model="addForm"
ref="addform"
v-show="!modeswitch"
:rules="addRules"
></el-form>
<div v-show="modeswitch" style="height: 459px; width: 100%">
<code-mirror
ref="addcodeform"
v-model:value="cmadd.value"
v-model:id="cmadd.id"
@set-form="setForm"
></code-mirror>
</div>
<template #footer>
<span class="dialog-footer">
<el-button class="button-grey" @click="addclose">取 消</el-button>
<el-button
type="primary"
@click="addSubmit"
>创 建</el-button
>
</span>
</template>
</el-dialog>
<!--单纯编辑-->
<!--<code-mirror
ref="editfileform"
v-model:value="cmedit.value"
v-model:id="cmedit.id">
</code-mirror>-->
</template>
<script>
import CodeMirror from "@/components/CodeMirror";
import { ref, watch, } from "vue";
import YAML from "json2yaml";
const getYAMLJS = require("yamljs");
let Base64 = require("js-base64").Base64;
export default {
setup() {
//add
const modeswitch = ref(false);
const addVisible = ref(false);
const addForm = ref({});
const addRules = ref();
let cmadd = ref({
value: "dxvd",
id: 1,
});
addForm.value = {
//json
};
//rules
addRules.value = {};
//TODO创建;
cmadd.value.value = YAML.stringify(addForm.value);
function add() {
if (addform.value) addform.value.resetFields();
addVisible.value = true;
}
//change事件:code变化=>表单变化
function setForm(val) {
addForm.value = getYAMLJS.parse(val);
}
watch(
() => addForm.value,
() => {
//watch监控表单变化=>code变化
cmadd.value.value = YAML.stringify(addForm.value);
},
{
deep: true,
}
);
function addclose() {
addVisible.value = false;
}
function addSubmit() {
let params = getYAMLJS.parse(cmadd.value.value);
//判断->提交
}
return {
addform,
addForm,
addRules,
addVisible,
add,
modeswitch,
addclose,
cmadd,
setForm,
addSubmit,
};
},
components: {
CodeMirror,
},
};
</script>
网友评论