diff --git a/src/App.vue b/src/App.vue index 1892bfc..ed73382 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,8 @@ @@ -26,7 +27,7 @@ import { ref, watch, useTemplateRef, nextTick, onMounted, onUnmounted } from "vu import { invoke } from "@tauri-apps/api/core"; import { readTextFile, writeTextFile, writeFile, exists } from '@tauri-apps/plugin-fs'; import { save } from '@tauri-apps/plugin-dialog'; -import { Message, Notice } from 'view-ui-plus' +import { Message, Notice, Modal } from 'view-ui-plus' import { GetSingleArticle, UpdateArticle } from '/src/utils/userHandler'; // 原始示例数据,仅供参考 @@ -86,6 +87,32 @@ watch(currentFilePath, async (newFilePath) => { localStorage.setItem('currentSelectedFilePath', newFilePath); await readFileContent(newFilePath); }) +// 切换文件时,如果当前文件的变动未保存,允许用户取消切换动作,保存当前文件内容 +const confirmSwitchingFile = () => { + // 判断当前文件内容是否被修改 + const lastSaveTimeValue = lastSaveTime.get(currentFilePath.value); + const isUpdated = lastSaveTimeValue && lastUpdateTime.value > lastSaveTimeValue; + return new Promise((resolve) => { + // 如果当前文件内容未被修改,允许切换文件 + if (!isUpdated) { + resolve(true); + return; + } + // 如果当前文件内容被修改,允许用户取消切换,可以保存后再切换 + Modal.confirm({ + title: '当前文件的内容变动未保存', + content: `

${currentFilePath.value} 内容被修改但仍未保存,确认切换文件?

注:确认切换之后,内容变动会丢失

`, + okText: "仍然切换", + cancelText: "取消切换", + onOk: () => { + resolve(true); + }, + onCancel: () => { + resolve(false); + } + }); + }); +} const getFileNameFromFilePath = (filePath) => { const fullFileName = filePath.split('/').pop(); const splitResult = fullFileName.split("."); diff --git a/src/components/LeftSidebar.vue b/src/components/LeftSidebar.vue index 568bc3c..10f9a3e 100644 --- a/src/components/LeftSidebar.vue +++ b/src/components/LeftSidebar.vue @@ -8,7 +8,7 @@ @update:rootPath="changeRootPath" @folder-selected="showFileTree" /> + :confirmSwitchingNode="confirmSwitchingFile" :specifyFileSuffix="['md']" @file-selected="fileSelected" /> @@ -32,6 +32,11 @@ defineProps({ required: false, default: '' }, + confirmSwitchingFile: { + type: Function, + required: false, + default: undefined, + } }); const emit = defineEmits([ diff --git a/src/components/UI/FolderTree.vue b/src/components/UI/FolderTree.vue index a4e483f..5ddabf9 100644 --- a/src/components/UI/FolderTree.vue +++ b/src/components/UI/FolderTree.vue @@ -60,6 +60,14 @@ export default { required: false, default: [], }, + // 切换节点前的确认函数。返回 Promise 对象,resolve(true) 表示切换节点,resolve(false) 表示取消切换节点 + confirmSwitchingNode: { + type: Function, + required: false, + default: () => new Promise((resolve) => { + resolve(true); + }), + }, }, data() { return { @@ -220,15 +228,22 @@ export default { return } - // 清除其他选中状态,为当前节点增加选中状态 - let selectedNodes = this.$refs.tree.getSelectedNodes() - selectedNodes.forEach(element => { - element.selected = false - }); - nodeRenderData.selected = true + this.confirmSwitchingNode().then((result) => { + // 如果用户取消了切换文件,则不做任何操作 + if (result === false) { + return; + } - // 向父组件暴露当前选中的文件 - this.$emit('file-selected', nodeRenderData); + // 清除其他选中状态,为当前节点增加选中状态 + let selectedNodes = this.$refs.tree.getSelectedNodes(); + selectedNodes.forEach(element => { + element.selected = false; + }); + nodeRenderData.selected = true; + + // 向父组件暴露当前选中的文件 + this.$emit('file-selected', nodeRenderData); + }); }, // 在父节点插入子节点 insertTreeNode(parentRenderData, nodeData, index) {