ABOUT ME

-

  • [ Electron + Vue ] 백업 및 불러오기 기능 구현
    Desktop App/Electron + Vue 2025. 11. 2. 12:52
    반응형

    메모앱을 이제 지속해서 업데이트를 하면서 index DB를 활용해서 데이터를 저장하다보니 막상 데이터를 옮길려면 직접 복붙을 해야하는 상황이어서 백업 파일을 활용해야할 것 같다고 생각들어 기능을 구현

     

    electron 의 dialog를 활용

    saveBackupMemo: (data) => ipcRenderer.invoke('save-backup', data),

     

    ipc 등록

    파라미터로 데이터를 받아서 데이터 객체를 Json으로 변환한다 이때의 확장자는 원하는 확장자를 선택해서 자유롭게 설정

    ipcMain.handle('save-backup', async (event,data) => {
        const today = formatDate(new Date());
    
        const defaultFileName = `yume-backup-${today}.ynote`;
        const { canceled, filePath } = await dialog.showSaveDialog({
            title: 'Save Yume Note Backup',
            defaultPath: defaultFileName,
            filters: [
                { name: 'Yume Note Backup File', extensions: ['ynote'] },
            ]
        })
    
        if (canceled) return { success: false }
    
        try {
            fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8')
            return { success: true, path: filePath }
        } catch (err) {
            console.error(err)
            return { success: false, error: err.message }
        }
    
        function formatDate(date) {
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2,'0');
            const day = String(date.getDate()).padStart(2,'0');
            return `${year}-${month}-${day}`;
        }
    })

     

    백업 버튼을 누르면 선택한 메모 리스트들을 파라미터로 전달.

    const onClickBackupConfirm = async () => {
      const result = await window.electronAPI?.saveBackupMemo(toRaw(backupMemoList.value))
    
      if(result.success) {
        toast.success(t('message.backupSuccess'))
      } else if(result.error) {
        toast.error(t('message.backupFail'))
      }
    }

     

    그러면 ipc에서 설정한 방식으로 파일 저장을 할 수 있다.

    이때 파일은 json으로 저장되며 해당 파일을 메모장으로 열어보면 json데이터를 확인할 수 있다.

    이후 이제해당 파일을 불러오는 기능을 구현

    이제 저장된 파일을 가져오도록 한다.

    ipcMain.handle('load-backup', async (event,path) => {
        const result = await dialog.showOpenDialog({
            title: 'Open Yume Note Backup',
            filters: [
                { name: 'Yume Note Backup', extensions: ['ynote'] },
            ],
            properties: ['openFile'],
            defaultPath: app.getPath('documents') // 기본 위치
        });
    
        if (result.canceled) {
            return { canceled: true };
        }
    
        const filePath = result.filePaths[0];
    
        try {
            const data = fs.readFileSync(filePath, 'utf-8');
            return { canceled: false, data: data, path: filePath };
        } catch (error) {
            return { canceled: false, error: error.message };
        }
    })

     

    가져온 데이터는 json으로 되어있기 떄문에 json을 객체로 변환시켜준다.

    이후 해당 변환된 값을 indexDB에 추가해준다.

    const onClickLoadBackup = async () => {
      const result = await window.electronAPI?.loadBackupMemo();
    
      if(result.canceled) {
        return
      }
    
      if(result.error) {
        toast.error(t('message.loadBackupFail'))
        return
      }
    
      const backupData= result.data
      const parseData = JSON.parse(backupData)
    
      parseData.forEach((memo: Memo) => {
        if(padStore.currentMemoPad == null) return
    
        memoStore.add(memo)
      })
    }
    728x90
    반응형