|
197 | 197 | return editor.value.storage.markdown.getMarkdown(); |
198 | 198 | }; |
199 | 199 |
|
200 | | - let isUpdatingFromOutside = false; // A flag to prevent infinite update loops |
| 200 | + // Cache of the latest markdown value emitted by this component. Used to |
| 201 | + // detect when an incoming prop.value is just our own emitted value echoed |
| 202 | + // back, so we can skip unnecessary re-rendering of the editor content. |
| 203 | + let lastEmittedMarkdown = null; |
201 | 204 |
|
202 | 205 | watch( |
203 | 206 | () => props.mode, |
|
217 | 220 | watch( |
218 | 221 | () => props.value, |
219 | 222 | newValue => { |
| 223 | + // If the incoming value matches what we last emitted, the editor |
| 224 | + // already reflects this content, so skip re-rendering to avoid |
| 225 | + // unnecessary work and resetting the editor state. |
| 226 | + if (newValue === lastEmittedMarkdown) { |
| 227 | + return; |
| 228 | + } |
| 229 | +
|
220 | 230 | const processedContent = preprocessMarkdown(newValue); |
221 | 231 |
|
222 | 232 | if (!editor.value) { |
|
228 | 238 |
|
229 | 239 | const editorContent = getMarkdownContent(); |
230 | 240 | if (editorContent !== newValue) { |
231 | | - isUpdatingFromOutside = true; |
232 | 241 | editor.value.commands.setContent(processedContent, false); |
233 | | - nextTick(() => { |
234 | | - isUpdatingFromOutside = false; |
235 | | - }); |
236 | 242 | } |
237 | 243 | }, |
238 | 244 | { immediate: true }, |
239 | 245 | ); |
240 | 246 |
|
241 | | - // sync changes from the editor to the parent component |
242 | | - watch( |
243 | | - () => editor.value?.state, |
244 | | - () => { |
245 | | - if ( |
246 | | - !editor.value || |
247 | | - !isReady.value || |
248 | | - isUpdatingFromOutside || |
249 | | - !editor.value.storage?.markdown |
250 | | - ) { |
251 | | - return; |
252 | | - } |
| 247 | + // sync changes from the editor to the parent component, only on blur |
| 248 | + const emitMarkdownUpdate = () => { |
| 249 | + if (!editor.value || !isReady.value || !editor.value.storage?.markdown) { |
| 250 | + return; |
| 251 | + } |
253 | 252 |
|
254 | | - const markdown = getMarkdownContent(); |
255 | | - if (markdown !== props.value) { |
256 | | - emit('update', markdown); |
257 | | - } |
258 | | - }, |
259 | | - { deep: true }, |
260 | | - ); |
| 253 | + const markdown = getMarkdownContent(); |
| 254 | + if (markdown !== props.value) { |
| 255 | + lastEmittedMarkdown = markdown; |
| 256 | + emit('update', markdown); |
| 257 | + } |
| 258 | + }; |
| 259 | +
|
| 260 | + // Emit the markdown update only when the editor loses focus (blur). |
| 261 | + watch(isFocused, (focused, wasFocused) => { |
| 262 | + if (wasFocused && !focused) { |
| 263 | + emitMarkdownUpdate(); |
| 264 | + } |
| 265 | + }); |
261 | 266 |
|
262 | 267 | const handleContainerKeydown = event => { |
263 | 268 | if (event.key === 'Enter') { |
|
0 commit comments