fix(note-editor): 优化自动保存机制,解决切换笔记时的保存问题
- 修复了在切换笔记时意外触发自动保存的问题- 引入标志位区分用户输入和程序加载内容 -优化了自动保存的防抖逻辑,提高用户体验 - 删除了不必要的组件代码,精简结构
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
|
||||
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
|
||||
import Vditor from 'vditor';
|
||||
import 'vditor/dist/index.css';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@@ -26,147 +26,4 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['back', 'save-success']);
|
||||
|
||||
const vditor = ref(null);
|
||||
const saveStatus = ref('空闲');
|
||||
let debounceTimer = null;
|
||||
|
||||
const initVditor = () => {
|
||||
vditor.value = new Vditor('vditor-editor', {
|
||||
height: 'calc(100vh - 120px)',
|
||||
mode: 'ir',
|
||||
after: () => {
|
||||
if (props.editData && props.editData.content) {
|
||||
vditor.value.setValue(props.editData.content);
|
||||
}
|
||||
},
|
||||
input: (value) => {
|
||||
saveStatus.value = '正在输入...';
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(() => {
|
||||
handleSave(value);
|
||||
}, 2000);
|
||||
},
|
||||
upload: {
|
||||
accept: 'image/*',
|
||||
handler(files) {
|
||||
handleImageUpload(files);
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleImageUpload = async (files) => {
|
||||
const file = files;
|
||||
if (!file) return;
|
||||
|
||||
try {
|
||||
const promise = await uploadImage(file);
|
||||
if (promise.url == null) {
|
||||
ElMessage.error(promise.msg || '图片上传失败');
|
||||
return;
|
||||
}
|
||||
const fullUrl = `${import.meta.env.VITE_API_BASE_URL}${promise.url}`;
|
||||
vditor.value.insertValue(``);
|
||||
} catch (error) {
|
||||
ElMessage.error('图片上传失败: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = async (content) => {
|
||||
saveStatus.value = '正在保存...';
|
||||
try {
|
||||
const payload = {
|
||||
id: props.editData.id,
|
||||
title: props.editData.title,
|
||||
groupingId: props.editData.groupingId,
|
||||
content: content,
|
||||
fileName: props.editData.fileName || `${props.editData.title}.md`,
|
||||
isPrivate: props.editData.isPrivate,
|
||||
};
|
||||
|
||||
const response = await updateMarkdown(payload);
|
||||
emit('save-success', response);
|
||||
saveStatus.value = '已保存';
|
||||
ElMessage.success('保存成功');
|
||||
} catch (error) {
|
||||
saveStatus.value = '保存失败';
|
||||
ElMessage.error('保存失败: ' + (error.response?.data?.message || error.message));
|
||||
}
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
if (vditor.value) {
|
||||
handleSave(vditor.value.getValue());
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initVditor();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (vditor.value) {
|
||||
vditor.value.destroy();
|
||||
}
|
||||
clearTimeout(debounceTimer);
|
||||
});
|
||||
|
||||
watch(() => props.editData, (newData) => {
|
||||
if (vditor.value && newData) {
|
||||
vditor.value.setValue(newData.content || '');
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
// Expose the save method to the parent
|
||||
defineExpose({ save });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.note-editor-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.editor-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: var(--box-shadow-light);
|
||||
}
|
||||
|
||||
.dark-theme .editor-header {
|
||||
background-color: rgba(30, 30, 47, 0.8);
|
||||
}
|
||||
|
||||
.editor-title {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.save-status {
|
||||
font-size: 14px;
|
||||
color: var(--text-color-secondary);
|
||||
width: 80px; /* Give it a fixed width to prevent layout shifts */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vditor {
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
const emit = defineEmits
|
||||
Reference in New Issue
Block a user