feat: 实现保存,显示隐藏目录等功能
This commit is contained in:
parent
f514f885df
commit
8895ddf9a4
@ -60,6 +60,7 @@
|
||||
|
||||
1. `npm install md-editor-v3 --save`
|
||||
2. 在 src/components/MainEditor.vue 组件里使用 md-editor-v3 组件
|
||||
3. 实现保存功能;自定义工具栏实现显示/隐藏目录以及发布等功能
|
||||
|
||||
### 调试应用
|
||||
|
||||
|
||||
25
src/App.vue
25
src/App.vue
@ -12,7 +12,7 @@
|
||||
<template #right>
|
||||
<div ref="splitRight" class="split-right">
|
||||
<MainEditor ref="mainEditor" v-model:markdownCode="markdownCode"
|
||||
:save="writeFileContent">
|
||||
v-model:leftSidebarState="leftSidebarState" :save="writeFileContent">
|
||||
</MainEditor>
|
||||
</div>
|
||||
</template>
|
||||
@ -36,24 +36,35 @@ async function greet() {
|
||||
}
|
||||
|
||||
// 使用 Split 组件动态控制页面左右布局
|
||||
const split = ref(0.2);
|
||||
const defaultSplit = 0.15; // 默认左侧边栏和右侧区域的比例为 1.5:8.5
|
||||
const split = ref(defaultSplit);
|
||||
const splitTrigger = useTemplateRef('splitTrigger');
|
||||
const splitRight = useTemplateRef('splitRight');
|
||||
const splitRightWidth = ref(0);
|
||||
const hiddenSplitLeft = ref("");
|
||||
const hiddenSplitLeft = ref('');
|
||||
const leftSidebarState = ref('open');
|
||||
watch(split, (newSplit) => {
|
||||
splitRightWidth.value = splitRight.value.offsetWidth;
|
||||
// 当 split 小于某个值时,隐藏左边布局
|
||||
if (newSplit < 0.05) {
|
||||
if (hiddenSplitLeft.value == "") {
|
||||
hiddenSplitLeft.value = "hidden"
|
||||
leftSidebarState.value = 'close';
|
||||
if (hiddenSplitLeft.value == '') {
|
||||
hiddenSplitLeft.value = 'hidden';
|
||||
}
|
||||
} else {
|
||||
if (hiddenSplitLeft.value == "hidden") {
|
||||
hiddenSplitLeft.value = ""
|
||||
leftSidebarState.value = 'open';
|
||||
if (hiddenSplitLeft.value == 'hidden') {
|
||||
hiddenSplitLeft.value = '';
|
||||
}
|
||||
}
|
||||
})
|
||||
watch(leftSidebarState, (state) => {
|
||||
if (state == 'open') {
|
||||
split.value = defaultSplit;
|
||||
} else {
|
||||
split.value = 0;
|
||||
}
|
||||
})
|
||||
|
||||
// 监听根目录路径。如果之前已经选过目录,初始界面直接加载该目录
|
||||
const rootFolderPath = ref(localStorage.getItem('rootPathOfFolderTree') || "");
|
||||
|
||||
@ -2,7 +2,27 @@
|
||||
<Split v-model="split">
|
||||
<template #left>
|
||||
<MdEditor ref="editorRef" v-model="editorState.text" :id="editorState.id" :theme="editorState.theme"
|
||||
:style="{ height: editorState.height }" :toolbars="editorState.toolbars" :toolbarsExclude="['github']">
|
||||
:style="{ height: editorState.height }" :toolbars="editorState.toolbars" :toolbarsExclude="['github']"
|
||||
@onSave="onSave" @onHtmlChanged="getPreviewedHTML">
|
||||
<template #defToolbars>
|
||||
<NormalToolbar :title="leftSidebarState == 'open' ? '隐藏文件树' : '显示文件树'" @onClick="toggleLeftSideBar">
|
||||
<template #trigger>
|
||||
<Icon v-if="leftSidebarState == 'open'" type="ios-arrow-dropleft" size="22" />
|
||||
<Icon v-else type="ios-arrow-dropright" size="22" />
|
||||
</template>
|
||||
</NormalToolbar>
|
||||
<NormalToolbar :title="split == 1 ? '显示目录' : '隐藏目录'" @onClick="toggleCatalog">
|
||||
<template #trigger>
|
||||
<Icon :class="split == 1 ? '' : 'md-editor-toolbar-active'" type="ios-list-box-outline"
|
||||
size="22" />
|
||||
</template>
|
||||
</NormalToolbar>
|
||||
<NormalToolbar title="发布文章" @onClick="publish">
|
||||
<template #trigger>
|
||||
<Icon class="md-editor-icon" type="md-cloud-upload" size="22" />
|
||||
</template>
|
||||
</NormalToolbar>
|
||||
</template>
|
||||
</MdEditor>
|
||||
</template>
|
||||
<template #trigger>
|
||||
@ -18,7 +38,7 @@
|
||||
|
||||
<script setup>
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
import { MdEditor, MdCatalog } from 'md-editor-v3';
|
||||
import { MdEditor, MdCatalog, NormalToolbar } from 'md-editor-v3';
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { Message } from 'view-ui-plus'
|
||||
|
||||
@ -28,6 +48,11 @@ const props = defineProps({
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
leftSidebarState: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'open'
|
||||
},
|
||||
save: {
|
||||
type: Function,
|
||||
required: false,
|
||||
@ -39,10 +64,12 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:markdownCode',
|
||||
'update:leftSidebarState',
|
||||
]);
|
||||
|
||||
// 定义布局,主要用于在右边显示文章目录
|
||||
const split = ref(0.8);
|
||||
const split = ref(1);
|
||||
const defaultCatalogSplit = 0.2; // 默认目录和编辑器的比例为 8:2
|
||||
const hiddenSplitRight = split.value == 1 ? ref('hidden') : ref('');
|
||||
watch(split, (newSplit) => {
|
||||
if (newSplit > 0.95) {
|
||||
@ -65,6 +92,9 @@ const editorState = reactive({
|
||||
height: '100vh',
|
||||
text: props.markdownCode,
|
||||
toolbars: [
|
||||
0,
|
||||
1,
|
||||
'-',
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
@ -89,6 +119,7 @@ const editorState = reactive({
|
||||
'revoke',
|
||||
'next',
|
||||
'save',
|
||||
2,
|
||||
'=',
|
||||
'prettier',
|
||||
'pageFullscreen',
|
||||
@ -110,6 +141,41 @@ watch(() => editorState.text, (newCode) => {
|
||||
emit('update:markdownCode', newCode);
|
||||
})
|
||||
|
||||
const toggleLeftSideBar = () => {
|
||||
if (props.leftSidebarState == 'open') {
|
||||
emit('update:leftSidebarState', 'close');
|
||||
} else {
|
||||
emit('update:leftSidebarState', 'open');
|
||||
}
|
||||
}
|
||||
|
||||
const toggleCatalog = () => {
|
||||
if (split.value < 1) {
|
||||
split.value = 1;
|
||||
} else {
|
||||
split.value = 1 - defaultCatalogSplit;
|
||||
}
|
||||
}
|
||||
|
||||
const onSave = (v, h) => {
|
||||
// 调用 save 方法保存代码(参数 v 为 markdown code)
|
||||
props.save(v);
|
||||
|
||||
// 使用 h 可以在保存时直接获取 html
|
||||
// h.then((html) => {
|
||||
// console.log(html);
|
||||
// });
|
||||
};
|
||||
|
||||
const getPreviewedHTML = (html) => {
|
||||
console.log(html);
|
||||
}
|
||||
|
||||
const publish = () => {
|
||||
// TODO 调用接口将 markdown 源码或者 HTML 代码发布到云端
|
||||
Message.warning('抱歉,该功能暂未开放');
|
||||
}
|
||||
|
||||
// 对父组件暴露数据或方法
|
||||
defineExpose({})
|
||||
</script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user