chore: 优化 components 组件,抽象简化代码
This commit is contained in:
parent
ad813ffe75
commit
d336938e78
107
src/App.vue
107
src/App.vue
@ -12,11 +12,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #right>
|
<template #right>
|
||||||
<div ref="splitRight" class="split-right">
|
<div ref="splitRight" class="split-right">
|
||||||
<MarkdownEditor ref="markdownRef" width="100%" height="100%" :autoInit="false"
|
<MainEditor ref="mainEditor" v-model:markdownCode="markdownCode" :save="writeFileContent">
|
||||||
:markdownCode="markdownCode" :imageUpload="true" :imageUploadURL="imageUploadURLOfEditor"
|
</MainEditor>
|
||||||
:imageUploadURLChange="changeImageUploadURL" :onload="reloadEditorHeight"
|
|
||||||
:onFullScreenExit="handleWindowResize" @update:markdownCode="newCode => markdownCode = newCode"
|
|
||||||
:appendToolbar="appendToolbar" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Split>
|
</Split>
|
||||||
@ -24,8 +21,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import MarkdownEditor from './components/MarkdownEditor.vue'
|
|
||||||
import LeftSidebar from './components/LeftSidebar.vue'
|
import LeftSidebar from './components/LeftSidebar.vue'
|
||||||
|
import MainEditor from './components/MainEditor.vue'
|
||||||
import { ref, watch, useTemplateRef, onMounted, onUnmounted } from "vue";
|
import { ref, watch, useTemplateRef, onMounted, onUnmounted } from "vue";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { readTextFile, writeTextFile, exists } from '@tauri-apps/plugin-fs';
|
import { readTextFile, writeTextFile, exists } from '@tauri-apps/plugin-fs';
|
||||||
@ -57,7 +54,7 @@ watch(split, (newSplit) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 动态调整 MarkdownEditor 的宽度。如果不执行 reset 的话,CodeMirror 内部编辑器不会自适应宽度
|
// 动态调整 MarkdownEditor 的宽度。如果不执行 reset 的话,CodeMirror 内部编辑器不会自适应宽度
|
||||||
reloadEditorWidth()
|
mainEditor.value.resizeEditorWindow();
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听根目录路径。如果之前已经选过目录,初始界面直接加载该目录
|
// 监听根目录路径。如果之前已经选过目录,初始界面直接加载该目录
|
||||||
@ -74,80 +71,21 @@ watch(currentFilePath, async (newFilePath) => {
|
|||||||
await readFileContent(newFilePath);
|
await readFileContent(newFilePath);
|
||||||
})
|
})
|
||||||
|
|
||||||
// 加载 Markdown 编辑器
|
const mainEditor = ref(null);
|
||||||
const markdownRef = ref(null);
|
|
||||||
const markdownCode = ref("# Hello Markdown");
|
const markdownCode = ref("# Hello Markdown");
|
||||||
const appendToolbar = [
|
watch(markdownCode, (newMarkdownCode) => {
|
||||||
{
|
console.log("code be updated");
|
||||||
name: "|",
|
})
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "save-markdown-code",
|
|
||||||
icon: "fa-save", // font-awesome icon. 需确保在 editormd.css 中已定义
|
|
||||||
title: "保存当前内容",
|
|
||||||
shortcut: [
|
|
||||||
navigator.userAgent.toUpperCase().indexOf('MAC') >= 0 ? "Cmd-S" : "Ctrl-S"
|
|
||||||
],
|
|
||||||
handler: () => {
|
|
||||||
writeFileContent();
|
|
||||||
},
|
|
||||||
nofocus: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "publish",
|
|
||||||
icon: "fa-cloud-upload",
|
|
||||||
title: "发布文章",
|
|
||||||
handler: () => {
|
|
||||||
// TODO 调用接口将 markdown 源码或者 HTML 代码发布到云端
|
|
||||||
Message.warning('抱歉,该功能暂未开放');
|
|
||||||
},
|
|
||||||
nofocus: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
// 支持从 localStorage 读写 imageUploadURL
|
|
||||||
const imageUploadURLOfEditor = ref(localStorage.getItem('imageUploadURLOfEditor') || "");
|
|
||||||
function changeImageUploadURL(newImageUploadURL) {
|
|
||||||
console.log("new imageUploadURL: ", newImageUploadURL);
|
|
||||||
localStorage.setItem('imageUploadURLOfEditor', newImageUploadURL);
|
|
||||||
}
|
|
||||||
async function initMarkdownEditor() {
|
|
||||||
// 打开上一次选择的文件的内容
|
|
||||||
if (currentFilePath.value.length > 0) {
|
|
||||||
try {
|
|
||||||
markdownCode.value = await readTextFile(currentFilePath.value);
|
|
||||||
Message.success('已读取文件内容,并加载到编辑器中:' + currentFilePath.value);
|
|
||||||
} catch (err) {
|
|
||||||
Message.error('文件读取失败:' + err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
markdownRef.value.initEditor()
|
|
||||||
}
|
|
||||||
// 矫正 markdown 编辑器的高度
|
|
||||||
function reloadEditorHeight() {
|
|
||||||
markdownRef.value.resetHeight(window.innerHeight);
|
|
||||||
}
|
|
||||||
// 矫正 markdown 编辑器的宽度
|
|
||||||
function reloadEditorWidth() {
|
|
||||||
// 可以使用 splitRight.value.offsetWidth 也可以使用 100% 来调整
|
|
||||||
const width = splitRight.value.offsetWidth;
|
|
||||||
markdownRef.value.resetWidth("100%");
|
|
||||||
}
|
|
||||||
// 监听页面宽度和高度,调整 markdown 编辑器的高宽度
|
|
||||||
const handleWindowResize = () => {
|
|
||||||
reloadEditorHeight();
|
|
||||||
reloadEditorWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function readFileContent(filePath) {
|
async function readFileContent(filePath) {
|
||||||
try {
|
try {
|
||||||
markdownRef.value.setMarkdownCode(await readTextFile(filePath));
|
mainEditor.value.setMarkdownCode(await readTextFile(filePath));
|
||||||
currentFilePath.value = filePath;
|
currentFilePath.value = filePath;
|
||||||
Message.success('已读取文件内容,并加载到编辑器中:' + filePath);
|
Message.success('已读取文件内容,并加载到编辑器中:' + filePath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Message.error('文件读取失败:' + err);
|
Message.error('文件读取失败:' + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function writeFileContent() {
|
async function writeFileContent(markdownCode) {
|
||||||
// 如果未选择任何文件,则不触发写文件事件
|
// 如果未选择任何文件,则不触发写文件事件
|
||||||
if (currentFilePath.value.length == 0) {
|
if (currentFilePath.value.length == 0) {
|
||||||
Message.warning('当前编辑器暂未关联目标文件,请在左侧打开目录并选择一个文件')
|
Message.warning('当前编辑器暂未关联目标文件,请在左侧打开目录并选择一个文件')
|
||||||
@ -158,20 +96,29 @@ async function writeFileContent() {
|
|||||||
if (!exist) {
|
if (!exist) {
|
||||||
throw new Error(currentFilePath.value + " 文件不存在.");
|
throw new Error(currentFilePath.value + " 文件不存在.");
|
||||||
}
|
}
|
||||||
await writeTextFile(currentFilePath.value, markdownRef.value.getMarkdownCode())
|
await writeTextFile(currentFilePath.value, markdownCode)
|
||||||
Message.success('文件更新成功:' + currentFilePath.value);
|
Message.success('文件更新成功:' + currentFilePath.value);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Message.error('文件更新失败:' + err);
|
Message.error('文件更新失败:' + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onMounted(async () => {
|
||||||
onMounted(() => {
|
// 监听页面宽度和高度,调整 markdown 编辑器的高宽度
|
||||||
window.addEventListener('resize', handleWindowResize);
|
window.addEventListener('resize', mainEditor.value.resizeEditorWindow);
|
||||||
initMarkdownEditor();
|
// 打开上一次选择的文件的内容
|
||||||
})
|
if (currentFilePath.value.length > 0) {
|
||||||
|
try {
|
||||||
|
markdownCode.value = await readTextFile(currentFilePath.value);
|
||||||
|
Message.success('已读取文件内容,并加载到编辑器中:' + currentFilePath.value);
|
||||||
|
} catch (err) {
|
||||||
|
Message.error('文件读取失败:' + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainEditor.value.initMarkdownEditor();
|
||||||
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('resize', handleWindowResize);
|
window.removeEventListener('resize', mainEditor.value.resizeEditorWindow);
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import SelectFolder from './SelectFolder.vue';
|
import SelectFolder from './UI/SelectFolder.vue';
|
||||||
import FolderTree from './FolderTree.vue';
|
import FolderTree from './UI/FolderTree.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { mkdir, remove, create, exists, rename } from '@tauri-apps/plugin-fs';
|
import { mkdir, remove, create, exists, rename } from '@tauri-apps/plugin-fs';
|
||||||
import { Message } from 'view-ui-plus'
|
import { Message } from 'view-ui-plus'
|
||||||
|
|||||||
119
src/components/MainEditor.vue
Normal file
119
src/components/MainEditor.vue
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<template>
|
||||||
|
<MarkdownEditor ref="markdownRef" width="100%" height="100%" :appendToolbar="appendToolbar"
|
||||||
|
:autoInit="false" :markdownCode="markdownCode" @update:markdownCode="updateMarkdownCode"
|
||||||
|
:imageUpload="true" :imageUploadURL="imageUploadURLOfEditor" :imageUploadURLChange="changeImageUploadURL"
|
||||||
|
:onload="reloadEditorHeight" :onFullScreenExit="resizeEditorWindow" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import MarkdownEditor from './UI/MarkdownEditor.vue';
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { Message } from 'view-ui-plus'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
markdownCode: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
save: {
|
||||||
|
type: Function,
|
||||||
|
required: false,
|
||||||
|
default: (markdownCode) => {
|
||||||
|
console.log("save markdown code: " + markdownCode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
'update:markdownCode',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 加载 Markdown 编辑器
|
||||||
|
const markdownRef = ref(null);
|
||||||
|
const initMarkdownEditor = () => {
|
||||||
|
markdownRef.value.initEditor();
|
||||||
|
}
|
||||||
|
const getMarkdownCode = () => {
|
||||||
|
return markdownRef.value.getMarkdownCode();
|
||||||
|
}
|
||||||
|
const setMarkdownCode = (newMarkdownCode) => {
|
||||||
|
return markdownRef.value.setMarkdownCode(newMarkdownCode);
|
||||||
|
}
|
||||||
|
const updateMarkdownCode = (newMarkdownCode) => {
|
||||||
|
emit('update:markdownCode', newMarkdownCode); // 触发双向绑定更新
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持从 localStorage 读写 imageUploadURL
|
||||||
|
const imageUploadURLOfEditor = ref(localStorage.getItem('imageUploadURLOfEditor') || "");
|
||||||
|
function changeImageUploadURL(newImageUploadURL) {
|
||||||
|
console.log("new imageUploadURL: ", newImageUploadURL);
|
||||||
|
localStorage.setItem('imageUploadURLOfEditor', newImageUploadURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipboard(text) {
|
||||||
|
navigator.clipboard.writeText(text)
|
||||||
|
.then(() => Message.success('复制成功'))
|
||||||
|
.catch(err => Message.error('复制失败:', err));
|
||||||
|
}
|
||||||
|
const appendToolbar = [
|
||||||
|
{
|
||||||
|
name: "|",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "save-markdown-code",
|
||||||
|
icon: "fa-save", // font-awesome icon. 需确保在 editormd.css 中已定义
|
||||||
|
title: "保存当前内容",
|
||||||
|
shortcut: [
|
||||||
|
navigator.userAgent.toUpperCase().indexOf('MAC') >= 0 ? "Cmd-S" : "Ctrl-S"
|
||||||
|
],
|
||||||
|
handler: () => {
|
||||||
|
props.save(markdownRef.value.getMarkdownCode());
|
||||||
|
},
|
||||||
|
nofocus: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get-html-code",
|
||||||
|
icon: "fa-copy", // font-awesome icon. 需确保在 editormd.css 中已定义
|
||||||
|
title: "获取 HTML 代码(复制到粘贴板)",
|
||||||
|
handler: () => {
|
||||||
|
copyToClipboard(markdownRef.value.getPreviewedHTML())
|
||||||
|
},
|
||||||
|
nofocus: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "publish",
|
||||||
|
icon: "fa-cloud-upload",
|
||||||
|
title: "发布文章",
|
||||||
|
handler: () => {
|
||||||
|
// TODO 调用接口将 markdown 源码或者 HTML 代码发布到云端
|
||||||
|
Message.warning('抱歉,该功能暂未开放');
|
||||||
|
},
|
||||||
|
nofocus: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 矫正 markdown 编辑器的高度
|
||||||
|
function reloadEditorHeight() {
|
||||||
|
markdownRef.value.resetHeight(window.innerHeight);
|
||||||
|
}
|
||||||
|
// 矫正 markdown 编辑器的宽度
|
||||||
|
function reloadEditorWidth() {
|
||||||
|
// 可以使用 splitRight.value.offsetWidth 也可以使用 100% 来调整
|
||||||
|
// const width = splitRight.value.offsetWidth;
|
||||||
|
markdownRef.value.resetWidth("100%");
|
||||||
|
}
|
||||||
|
// 监听页面宽度和高度,调整 markdown 编辑器的高宽度
|
||||||
|
const resizeEditorWindow = () => {
|
||||||
|
reloadEditorHeight();
|
||||||
|
reloadEditorWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对父组件暴露数据或方法
|
||||||
|
defineExpose({
|
||||||
|
initMarkdownEditor,
|
||||||
|
getMarkdownCode,
|
||||||
|
setMarkdownCode,
|
||||||
|
resizeEditorWindow,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
Loading…
x
Reference in New Issue
Block a user