Browse Source

feat: ace demo 编写完毕

master
wangxiang 1 year ago
parent
commit
5fe22b9c4f
  1. 7
      src/components/AceEditor/src/AceEditor.tsx
  2. 2
      src/components/AceEditor/src/emits.ts
  3. 6
      src/components/AceEditor/src/types.ts
  4. 2
      src/locales/lang/en/routes/demo.ts
  5. 2
      src/locales/lang/zh-CN/routes/demo.ts
  6. 8
      src/router/routes/demo/comp.ts
  7. 39
      src/views/demo/editor/ace/index.vue
  8. 4
      src/views/demo/editor/ace/useAceEditor.vue
  9. 112
      src/views/demo/editor/ace/useAceEditorAdvanced.vue
  10. 82
      src/views/demo/editor/ace/useAceEditorReactive.vue

7
src/components/AceEditor/src/AceEditor.tsx

@ -18,6 +18,7 @@ import type { AceEditorState, AceEditorMethods, AceEditorProps } from './types';
import { deepMerge } from '/@/utils'; import { deepMerge } from '/@/utils';
import { useAppStore } from '/@/store/modules/app'; import { useAppStore } from '/@/store/modules/app';
import './ace-config'; import './ace-config';
import { isFunction } from '/@/utils/is';
export default defineComponent({ export default defineComponent({
name: 'AceEditor', name: 'AceEditor',
@ -35,7 +36,7 @@ export default defineComponent({
_isSettingContent: false, _isSettingContent: false,
}); });
const getProps = computed((): Recordable => { const getProps = computed((): AceEditorProps => {
return { return {
...props, ...props,
...(unref(propsRef) as any), ...(unref(propsRef) as any),
@ -66,6 +67,10 @@ export default defineComponent({
const content = editor.getValue(); const content = editor.getValue();
state._contentBackup = content; state._contentBackup = content;
emit('update:value', content); emit('update:value', content);
emit('change', content);
// 解决通过useAceEditor注册onChange时不起作用的问题
const { onChange } = unref(getProps);
onChange && isFunction(onChange) && onChange.call(undefined, content);
}); });
// Event Binding // Event Binding
editor.on('blur', (e: Event) => emit('blur', e)); editor.on('blur', (e: Event) => emit('blur', e));

2
src/components/AceEditor/src/emits.ts

@ -1,9 +1,9 @@
export const basicEmits = [ export const basicEmits = [
'register', 'register',
'update:value', 'update:value',
'change',
'blur', 'blur',
'input', 'input',
'change',
'changeSelectionStyle', 'changeSelectionStyle',
'changeSession', 'changeSession',
'copy', 'copy',

6
src/components/AceEditor/src/types.ts

@ -22,6 +22,12 @@ export interface AceEditorProps {
printMargin: boolean | number; printMargin: boolean | number;
minLines: number; minLines: number;
maxLines: number; maxLines: number;
/**
* Callback executed when editor content
* @param content
*/
onChange?: (content: string) => void;
} }
export interface AceEditorMethods { export interface AceEditorMethods {

2
src/locales/lang/en/routes/demo.ts

@ -54,7 +54,7 @@ export default {
aceEditor: 'Ace editor', aceEditor: 'Ace editor',
aceEditorBasic: 'Ace Basic', aceEditorBasic: 'Ace Basic',
useAceEditor: 'Use AceEditor', useAceEditor: 'Use AceEditor',
useAceEditorReactive: 'Use AceEditor Reactive', useAceEditorAdvanced: 'Use AceEditor Advanced',
tinymce: 'Rich text', tinymce: 'Rich text',
tinymceBasic: 'Basic', tinymceBasic: 'Basic',

2
src/locales/lang/zh-CN/routes/demo.ts

@ -53,7 +53,7 @@ export default {
aceEditor: 'Ace编辑器', aceEditor: 'Ace编辑器',
aceEditorBasic: 'ACE基础使用', aceEditorBasic: 'ACE基础使用',
useAceEditor: 'UseAceEditor', useAceEditor: 'UseAceEditor',
useAceEditorReactive: 'UseAceEditor响应', useAceEditorAdvanced: 'ACE高级使用',
tinymce: '富文本', tinymce: '富文本',
tinymceBasic: '基础使用', tinymceBasic: '基础使用',

8
src/router/routes/demo/comp.ts

@ -361,11 +361,11 @@ const comp: AppRouteModule = {
}, },
}, },
{ {
path: 'useAceEditorReactive', path: 'useAceEditorAdvanced',
name: 'useAceEditorReactiveDemo', name: 'useAceEditorAdvancedDemo',
component: () => import('/@/views/demo/editor/ace/useAceEditorReactive.vue'), component: () => import('/@/views/demo/editor/ace/useAceEditorAdvanced.vue'),
meta: { meta: {
title: t('routes.demo.editor.useAceEditorReactive'), title: t('routes.demo.editor.useAceEditorAdvanced'),
}, },
}, },
], ],

39
src/views/demo/editor/ace/index.vue

@ -6,23 +6,30 @@
> >
<template #extra> <template #extra>
<a-space size="middle"> <a-space size="middle">
<a-select v-model:value="state.lang"> 语言<a-select v-model:value="state.lang">
<a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option> <a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option>
</a-select> </a-select>
<a-select v-model:value="state.theme"> 主题<a-select v-model:value="state.theme">
<a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option> <a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option>
</a-select> </a-select>
</a-space> </a-space>
</template> </template>
<AceEditor v-model:value="state.content" <AceEditor v-model:value="state.content"
class="vue-ace-editor" class="vue-ace-editor"
@register="register" :lang="state.lang"
:theme="state.theme"
:options="{
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
}"
/> />
</PageWrapper> </PageWrapper>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, watch } from 'vue'; import { reactive, watch } from 'vue';
import { AceEditor, useAceEditor } from '/@/components/AceEditor'; import { AceEditor } from '/@/components/AceEditor';
import { PageWrapper } from '/@/components/Page'; import { PageWrapper } from '/@/components/Page';
const langs = ['json', 'javascript', 'html', 'yaml']; const langs = ['json', 'javascript', 'html', 'yaml'];
@ -33,26 +40,6 @@
content: '', content: '',
}); });
const [
register,
{
setProps,
blur,
focus,
getAceInstance,
selectAll
},
] = useAceEditor({
lang: state.lang,
theme: state.theme,
options: {
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
}
});
watch( watch(
() => state.lang, () => state.lang,
async lang => { async lang => {
@ -64,13 +51,9 @@
yaml: import('../../../../../pnpm-lock.yaml?raw'), yaml: import('../../../../../pnpm-lock.yaml?raw'),
}[lang] }[lang]
|| {}).default!; || {}).default!;
setProps({ lang });
}, },
{ immediate: true } { immediate: true }
); );
watch(() => state.theme, theme => setProps({ theme }));
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

4
src/views/demo/editor/ace/useAceEditor.vue

@ -6,10 +6,10 @@
> >
<template #extra> <template #extra>
<a-space size="middle"> <a-space size="middle">
<a-select v-model:value="state.lang"> 语言<a-select v-model:value="state.lang">
<a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option> <a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option>
</a-select> </a-select>
<a-select v-model:value="state.theme"> 主题<a-select v-model:value="state.theme">
<a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option> <a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option>
</a-select> </a-select>
</a-space> </a-space>

112
src/views/demo/editor/ace/useAceEditorAdvanced.vue

@ -0,0 +1,112 @@
<template>
<PageWrapper title="useAceEditor高级进阶使用示例"
contentFullHeight
fixedHeight
contentBackground
>
<template #extra>
<div class="mb-4">
<div class="mb-4">
<a-button class="mr-2" @click="handleFocus"> 获得焦点 </a-button>
<a-button class="mr-2" @click="handleBlur"> 失去焦点 </a-button>
<a-button class="mr-2" @click="handleSelectAll"> 全选 </a-button>
<a-button class="mr-2" @click="handleGetAceInstance"> 获取Ace编辑器实例 </a-button>
</div>
<a-space size="middle">
语言<a-select v-model:value="state.lang">
<a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option>
</a-select>
主题<a-select v-model:value="state.theme">
<a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option>
</a-select>
</a-space>
</div>
</template>
<AceEditor class="vue-ace-editor"
@register="register"
@focus="handleEmitFocus"
@blur="handleEmitBlur"
/>
</PageWrapper>
</template>
<script setup lang="ts">
import { reactive, watch } from 'vue';
import { AceEditor, useAceEditor } from '/@/components/AceEditor';
import { PageWrapper } from '/@/components/Page';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const langs = ['json', 'javascript', 'html', 'yaml'];
const themes = ['chrome', 'github', 'monokai', 'dracula'];
const state = reactive({
lang: 'json',
theme: 'chrome',
content: '',
});
const [register, { setProps, blur, focus, getAceInstance, selectAll }] = useAceEditor({
value: state.content,
lang: state.lang,
theme: state.theme,
options: {
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
},
onChange: content => state.content = content
});
watch(
() => state.lang,
async lang => {
state.content = (
await {
json: import('../../../../../package.json?raw'),
javascript: import('/@/components/AceEditor/src/ace-config.js?raw'),
html: import('../../../../../index.html?raw'),
yaml: import('../../../../../pnpm-lock.yaml?raw'),
}[lang] || {}).default!;
setProps({ value: state.content, lang });
},
{ immediate: true }
);
watch(() => state.theme, theme => setProps({ theme }));
function handleEmitFocus() {
console.log('获取ACE编辑焦点.');
}
function handleEmitBlur() {
console.log('失去ACE编辑焦点.');
}
function handleFocus() {
createMessage.info('请在控制台查看!');
focus();
}
function handleBlur() {
createMessage.info('请在控制台查看!');
blur();
}
function handleSelectAll() {
selectAll();
}
function handleGetAceInstance() {
createMessage.info('请在控制台查看!');
console.log(getAceInstance());
}
</script>
<style lang="less" scoped>
.vue-ace-editor {
font-size: 12px;
}
</style>

82
src/views/demo/editor/ace/useAceEditorReactive.vue

@ -1,82 +0,0 @@
<template>
<PageWrapper title="useAceEditor响应式组件示例"
contentFullHeight
fixedHeight
contentBackground
>
<template #extra>
<a-space size="middle">
<a-select v-model:value="state.lang">
<a-select-option v-for="(lang, index) of langs" :key="index" :value="lang"> {{ lang }} </a-select-option>
</a-select>
<a-select v-model:value="state.theme">
<a-select-option v-for="(theme, index) of themes" :key="index" :value="theme"> {{ theme }} </a-select-option>
</a-select>
</a-space>
</template>
<AceEditor v-model:value="state.content"
class="vue-ace-editor"
@register="register"
/>
</PageWrapper>
</template>
<script setup lang="ts">
import { reactive, watch } from 'vue';
import { AceEditor, useAceEditor } from '/@/components/AceEditor';
import { PageWrapper } from '/@/components/Page';
const langs = ['json', 'javascript', 'html', 'yaml'];
const themes = ['chrome', 'github', 'monokai', 'dracula'];
const state = reactive({
lang: 'json',
theme: 'chrome',
content: '',
});
const [
register,
{
setProps,
blur,
focus,
getAceInstance,
selectAll
},
] = useAceEditor({
lang: state.lang,
theme: state.theme,
options: {
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
}
});
watch(
() => state.lang,
async lang => {
state.content = (
await {
json: import('../../../../../package.json?raw'),
javascript: import('/@/components/AceEditor/src/ace-config.js?raw'),
html: import('../../../../../index.html?raw'),
yaml: import('../../../../../pnpm-lock.yaml?raw'),
}[lang]
|| {}).default!;
setProps({ lang });
},
{ immediate: true }
);
watch(() => state.theme, theme => setProps({ theme }));
</script>
<style lang="less" scoped>
.vue-ace-editor {
font-size: 12px;
}
</style>
Loading…
Cancel
Save