Skip to content

Commit

Permalink
feat: add codeEditor component
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb committed Apr 17, 2021
1 parent c04e894 commit a812685
Show file tree
Hide file tree
Showing 19 changed files with 1,159 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### ✨ Features

- 新增图形编辑器示例
- 新增代码编辑器(包含 Json 编辑器)

### ⚡ Performance Improvements

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@zxcvbn-ts/core": "^0.3.0",
"ant-design-vue": "^2.1.2",
"axios": "^0.21.1",
"codemirror": "^5.60.0",
"cropperjs": "^1.5.11",
"crypto-js": "^4.0.0",
"echarts": "^5.1.0",
Expand All @@ -64,6 +65,7 @@
"@commitlint/config-conventional": "^12.1.1",
"@iconify/json": "^1.1.330",
"@purge-icons/generated": "^0.7.0",
"@types/codemirror": "^0.0.109",
"@types/crypto-js": "^4.0.1",
"@types/fs-extra": "^9.0.11",
"@types/inquirer": "^7.3.1",
Expand Down
8 changes: 8 additions & 0 deletions src/components/CodeEditor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { App } from 'vue';
import codeEditor from './src/CodeEditor.vue';

export const CodeEditor = Object.assign(codeEditor, {
install(app: App) {
app.component(codeEditor.name, codeEditor);
},
});
51 changes: 51 additions & 0 deletions src/components/CodeEditor/src/CodeEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div class="h-full">
<CodeMirrorEditor :value="getValue" @change="handleValueChange" :mode="mode" />
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
import { isString } from '/@/utils/is';
const MODE = {
JSON: 'application/json',
html: 'htmlmixed',
js: 'javascript',
};
export default defineComponent({
name: 'CodeEditor',
components: { CodeMirrorEditor },
props: {
value: {
type: [Object, String],
},
mode: {
type: String,
default: MODE.JSON,
},
},
emits: ['change'],
setup(props, { emit }) {
const getValue = computed(() => {
const { value, mode } = props;
if (mode === MODE.JSON) {
return isString(value)
? JSON.stringify(JSON.parse(value), null, 2)
: JSON.stringify(value, null, 2);
}
return value;
});
function handleValueChange(v) {
emit('change', v);
}
return {
handleValueChange,
getValue,
};
},
});
</script>
125 changes: 125 additions & 0 deletions src/components/CodeEditor/src/codemirror/CodeMirror.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<div class="relative h-100 !h-full w-full overflow-hidden" ref="el"> </div>
</template>

<script lang="ts">
import {
ref,
onMounted,
onUnmounted,
watchEffect,
watch,
defineComponent,
unref,
nextTick,
} from 'vue';
import { useDebounceFn } from '@vueuse/core';
import { useAppStore } from '/@/store/modules/app';
import CodeMirror from 'codemirror';
import './codemirror.css';
import 'codemirror/theme/idea.css';
import 'codemirror/theme/material-palenight.css';
// modes
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed';
export default defineComponent({
props: {
mode: {
type: String,
default: 'application/json',
},
value: {
type: String,
default: '',
},
readonly: {
type: Boolean,
default: false,
},
},
emits: ['change'],
setup(props, { emit }) {
const el = ref();
let editor: Nullable<CodeMirror.Editor>;
const debounceRefresh = useDebounceFn(refresh, 100);
const appStore = useAppStore();
watch(
() => props.value,
async (v) => {
await nextTick();
const oldValue = editor?.getValue();
v && v !== oldValue && editor?.setValue(v);
},
{ flush: 'post' }
);
watchEffect(() => {
editor?.setOption('mode', props.mode);
});
watch(
() => appStore.getDarkMode,
async () => {
setTheme();
},
{
immediate: true,
}
);
function setTheme() {
unref(editor)?.setOption(
'theme',
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight'
);
}
function refresh() {
editor?.refresh();
}
async function init() {
const addonOptions = {
autoCloseBrackets: true,
autoCloseTags: true,
foldGutter: true,
gutters: ['CodeMirror-linenumbers'],
};
editor = CodeMirror(el.value!, {
value: '',
mode: props.mode,
readOnly: props.readonly,
tabSize: 2,
theme: 'material-palenight',
lineWrapping: true,
lineNumbers: true,
...addonOptions,
});
editor?.setValue(props.value);
setTheme();
editor?.on('change', () => {
emit('change', editor?.getValue());
});
}
onMounted(async () => {
await nextTick();
init();
window.addEventListener('resize', debounceRefresh);
setTimeout(refresh, 50);
});
onUnmounted(() => {
window.removeEventListener('resize', debounceRefresh);
editor = null;
});
return { el };
},
});
</script>
21 changes: 21 additions & 0 deletions src/components/CodeEditor/src/codemirror/codeMirror.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import CodeMirror from 'codemirror';
import './codemirror.css';
import 'codemirror/theme/idea.css';
import 'codemirror/theme/material-palenight.css';
// import 'codemirror/addon/lint/lint.css';

// modes
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed';
// addons
// import 'codemirror/addon/edit/closebrackets';
// import 'codemirror/addon/edit/closetag';
// import 'codemirror/addon/comment/comment';
// import 'codemirror/addon/fold/foldcode';
// import 'codemirror/addon/fold/foldgutter';
// import 'codemirror/addon/fold/brace-fold';
// import 'codemirror/addon/fold/indent-fold';
// import 'codemirror/addon/lint/json-lint';
// import 'codemirror/addon/fold/comment-fold';
export { CodeMirror };
Loading

0 comments on commit a812685

Please sign in to comment.