亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

ホームページ バックエンド開発 Golang シンプルなパスワード マネージャー デスクトップ アプリ: Golang の Wails フレームワークへの進(jìn)出 (パート 2)

シンプルなパスワード マネージャー デスクトップ アプリ: Golang の Wails フレームワークへの進(jìn)出 (パート 2)

Dec 30, 2024 am 09:50 AM

プログラマーの皆さん、こんにちは!この短いシリーズの最初の部分では、Wails フレームワークで作成したパスワードを保存および暗號化するためのデスクトップ アプリケーションの作成と操作について説明しました。また、Go バックエンドとそれをフロントエンド側(cè)にバインドする方法についても説明しました。

このパートでは、ユーザー インターフェイスを扱います。その投稿で述べたように、Wails を使用すると、Vanilla JS を含む任意の Web フレームワークを使用して GUI を構(gòu)築できます。先ほども言いましたが、Wails の作成者は常に Svelte を第一候補として挙げているため、Svelte を気に入っているようです。 Wails CLI (現(xiàn)在のバージョン) は、Svelte Typescript (wails init -n myproject -t svelte-ts) でプロジェクトを作成するように要求すると、Svelte3 でスキャフォールディングを生成します。すでにお話ししたように、Svelte5 (およびその新機能) を使用したい場合は、その作成を自動化する bash スクリプトがあります (いずれの場合も、Wails CLI をインストールする必要があります)。さらに、Taildwindcss Daisyui が追加されており、インターフェースのデザインに最適な組み合わせであると思われます。

実のところ、私は最初に Vanilla JsVue を使用し、次に React を使用しました。さらに、多くの人にとって HTMX (これは大好きだと言わざるを得ません ??)。しかし、Svelte は最初から戀に落ちます。私が初めてこれを使用したのは、Wails を試しているときだったと言わざるを得ません (そして、これからも使い続けることを約束します…)。しかし、Web フレームワークは快適ですが、フロントエンドはそれほど簡単ではないことをバックエンド開発者に思い出させる必要があります?!!

しかし、本題に入りましょう。

I - フロントエンド構(gòu)造の概要

Web フレームワークを使用したことがある場合は、Wails CLI が內(nèi)部で ViteJs を使用していることがすぐにわかるでしょう。

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

Vite によって生成された Web フレームワークを使用したことがある場合は、その設(shè)定ファイルに驚かないでしょう。ここでは Svelte5 (さらに Taildwindcss Daisyui の構(gòu)成) を使用します。これは、すでに説明したように、獨自の bash スクリプトを生成するものです。また、フロントエンドの開発を容易にする TypeScript も使用しているため、その構(gòu)成も確認(rèn)できます。

しかし、この説明で重要なことは、wailsjs フォルダーの內(nèi)容です。ここで、Wails によるコンピレーションが魔法を発揮しました。 go サブフォルダーは、フロントエンドと対話する必要があるバックエンド部分の Js/Ts に「変換」されたメソッドが保存される場所です。たとえば、main/App.js (またはその TypeScript バージョン main/App.d.ts) には、アプリ構(gòu)造のエクスポートされた (パブリック) メソッドがすべて存在します。

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

全員が約束を返します。 Promise が戻り値の型として使用される Go 構(gòu)造體を「ラップ」するか、それぞれの関數(shù)が引數(shù)の型を取る場合、Go に対応するクラスを含むモジュール (models.ts、この場合は TypeScript を使用するため型付けされます) が存在します。名前空間內(nèi)の構(gòu)造體とそのコンストラクター。

さらに、ランタイム サブフォルダーには Go のランタイム パッケージのすべてのメソッドが含まれており、これによりバックエンドでリッスンまたはバックエンドから送出されるウィンドウとイベントをそれぞれ操作できるようになります。

src フォルダーには、他の Web アプリケーションと同様に、Vite によってコンパイルされて「frontend/dist」に保存される (そして最終的な実行可能ファイルに埋め込まれる) ファイルが含まれています。 Tailwindcss を使用しているため、style.css には基本的な Tailwind 設(shè)定と使用する必要がある CSS クラスが含まれていることに注意してください。また、インターフェースに Web テクノロジーを使用する利點として、1 つ以上のフォント (フォルダー アセット/フォント) を簡単に使用したり、交換したりできることが挙げられます。

この概要の最後に、開発モード (wails dev) でコンパイルすると、ホットリロードができることに加えて、(バックエンドとフロントエンドの両方で) 行われた変更を観察できるだけではないことに注意してください。アプリケーション ウィンドウ自體だけでなく、Web サーバーが起動しているため、アドレス http://localhost:34115 を介して Web ブラウザでも実行できます。これにより、お気に入りのブラウザ開発拡張機能を使用できるようになります。 Wails 自身がいくつかの非常に便利な開発ツールを提供していると言わなければなりませんが、アプリケーション ウィンドウを右クリックし (開発モードのみ)、[要素の検査] を選択すると次のようになります。

A minimalist password manager desktop app: a foray into Golang

II - それでは、HTML、CSS、JavaScript について詳しく見ていきましょう。


// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;

ご覧のとおり、Svelte に追加した JavaScript パッケージは 4 つあります (前述の Tailwindcss Daisyui とは別に):

  • svelte-copy、ユーザー名とパスワードをクリップボードに簡単にコピーできるようにします。
  • svelte-i18n、i18n 処理用、つまりユーザーがアプリケーションの言語を変更できるようにします。
  • svelte-spa-router、Svelte 用の小さなルーティング ライブラリ。これにより、アプリケーション ウィンドウでのビューの変更が簡単になります。この場合、提供される「公式」ルーティングを使用する価値がないからです。 SvelteKit.
  • sweetalert2、基本的にはモーダル/ダイアログ ボックスを簡単かつ迅速に作成するために使用します。

すべての SPA のエントリ ポイントは main.js (または main.ts) ファイルなので、そこから始めましょう:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

Wails CLI によって生成されたスケルトンに追加したものを強調(diào)表示しました。 svelte-i18n ライブラリでは、フォールバック/初期 言語の設(shè)定と同時に、翻訳を含む JSON ファイルを main.js/ts ファイルに登録する必要があります (ただし、これは、ユーザーが好みとして選択した內(nèi)容に基づいて後で操作されます)。翻訳を含む JSON ファイルの形式は次のとおりです:

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;

このライブラリのシステムは、Svelte アプリケーションの翻訳を容易にするのに簡単で便利だと思います (詳細(xì)についてはドキュメントを參照してください):

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

このようなサイトを使用すると、JSON ファイルをさまざまな言語に翻訳できます。ただし、問題は、.svelte ファイルに $format を入力するときに手動でファイルを追跡する必要があり、面倒でエラーが発生しやすいことです。このタスクを自動化する方法がわかりません。ご存知の方がいらっしゃいましたら、教えていただければ幸いです。

他の Svelte アプリケーションと同様に、インターフェイスを構(gòu)築する次のステップは App.svelte ファイルです。

/* main.ts */

import { mount } from 'svelte'
import './style.css'
import App from './App.svelte'
import { addMessages, init } from "svelte-i18n"; // ? ?
import en from './locales/en.json'; // ? ?
import es from './locales/es.json'; // ? ?

addMessages('en', en); // ? ?
addMessages('es', es); // ? ?

init({
  fallbackLocale: 'en', // ? ?
  initialLocale: 'en', // ? ?
});

const app = mount(App, {
  target: document.getElementById('app')!,
})

export default app

ここでは、アプリケーションのコンパイル時に自動的に生成され、struct App のパブリック メソッドとして宣言された バインディングである GetMasterPassword を使用します (このシリーズの最初の部分を參照)。この関數(shù)はデータベースにクエリを?qū)g行し、データベースにマスター パスワードが登録されている場合は、ユーザーがすでに登録されているものとみなし (ブール値をラップする Promise を返します)、殘りの部分にアクセスできるようにするためにそのパスワードを入力するよう求めます。ビューの。データベースにマスター パスワードがない場合、ユーザーは「新規(guī)」とみなされ、初めてアプリケーションに入るために獨自のパスワードを生成することが求められます。

最後に、Login.svelte コンポーネントをマウントするときに、アプリケーションの殘りの部分にとって重要な作業(yè)を行います。すでに見たように、svelte-i18n ライブラリでは初期言語コードの宣言が強制されますが、Login.svelte をマウントするときに、言語コードが保存されているかどうかをデータベースに (GetLanguage バインディングを使用して) 確認(rèn)します。データベースが空の文字列を返した場合、つまり、ユーザーの設(shè)定として設(shè)定された言語がない場合、svelte-i18n は、initialLocale として設(shè)定された値を使用します。代わりに言語が設(shè)定されている場合は、その言語が設(shè)定され (locale.set(result);)、「change_titles」イベントが発行され、アプリのタイトル バーとネイティブ ダイアログの翻訳されたタイトルが渡されます。バックエンドが処理するもの:

/* frontend/src/locales/en.json */

{
    "language": "Language",
    "app_title": "Nu-i uita ? minimalist password store",
    "select_directory": "Select the directory where to save the data export",
    "select_file": "Select the backup file to import",
    "master_password": "Master Password ?",
    "generate": "Generate",
    "insert": "Insert",
    "login": "Login",
    ...
}


/* frontend/src/locales/es.json */

{
    "language": "Idioma",
    "app_title": "Nu-i uita ? almacén de contrase?as minimalista",
    "select_directory": "Selecciona el directorio donde guardar los datos exportados",
    "select_file": "Selecciona el archivo de respaldo que deseas importar",
    "master_password": "Contrase?a Maestra ?",
    "generate": "Generar",
    "insert": "Insertar",
    "login": "Inciar sesión",
    ...
}

ログインを処理するロジックは次のとおりです:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

簡単に言うと、ユーザーが入力した內(nèi)容を取得する入力にバインドされた狀態(tài)である newPassword は、最初に onLogin によってチェックされ、少なくとも 6 文字が含まれているかどうか、およびすべてが ASCII 文字であるかどうかが確認(rèn)されます。つまり、この小さな関數(shù) const isAscii = (str: string): boolean によって、それらはわずか 1 バイトの長さになります (その理由については、このシリーズのパート 1 を參照してください)。 => /^[x00-x7F] $/.test(str);。チェックが失敗した場合、関數(shù)は戻り、ユーザーに警告 トースト を表示します。その後、データベースにマスター パスワードが保存されていない場合 (isLogin = false)、ユーザーが入力した內(nèi)容はすべて SaveMasterPassword 関數(shù) (Wails によって生成されたバインディング) によって保存されます。 Promise が正常に解決された場合 (データベースに保存されているレコードの Id として uuid 文字列を返す)、ユーザーは svelte-spa-router によってホーム ビューに移動します。ライブラリのプッシュメソッド。逆に、パスワードの長さと 非 ASCII 文字の有無のチェックに合格し、DB 內(nèi)にマスター パスワードがある (isLogin = true) 場合、CheckMasterPassword 関數(shù)は保存されているパスワードと照合してその ID を検証し、次のいずれかを?qū)g行します。ユーザーをホーム ビューに移動します (プロミスは true で解決されます)。または、入力されたパスワードが間違っていたことを示す トースト が表示されます。

アプリケーションの中心となるビューであると同時に、最も複雑なのはホーム ビューです。その HTML は実際には 3 つのコンポーネントに分割されています。検索入力のある上部のボタン バー (TopActions コンポーネント)、下部のボタン バー (BottomActions コンポーネント)、および保存されたパスワード エントリの総數(shù)またはそのリストが表示される中央領(lǐng)域です。スクロール可能なウィンドウ (EntriesList コンポーネント):

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;

つまり、検索狀態(tài) (searchTerms) を空の文字列にし、検索語がある場合はリセットされ、リスト全體が表示されます。一方、親コンポーネントがリストを表示または非表示にするように、showList 狀態(tài) (TopActions の props isEntriesList) を切り替えます。

上の図からわかるように、両方の子コンポーネントは親の searchTerms 狀態(tài)と同じ props を共有します。 TopActions コンポーネントはユーザーからの入力を取得し、それを狀態(tài)として親コンポーネント Home に渡し、次にそれを props としてその子コンポーネント EntriesList.

に渡します。

完全なリスト、またはユーザーが入力した検索語でフィルターされたリストを表示するメイン ロジックは、期待どおり、EntriesList コンポーネントによって実行されます。

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

前述したように、2 つのプロパティ (listCounter と search) が受信され、狀態(tài)が維持されます (let エントリ: models.PasswordEntry[] = $state([]);)。ユーザーの要求に応じてコンポーネントがマウントされると、バックエンドは保存されたパスワード エントリの完全なリストを要求されます。検索語がない場合は、狀態(tài)に保存されます。存在する場合、取得された配列の単純なフィルタリングが実行され、次の狀態(tài)に保存されます:

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;

表示されたリストで、ユーザーは 2 つのアクションを?qū)g行できます。 1 つ目は、エントリの詳細(xì)を表示することで、対応するボタンをクリックすると実行されます。 Push(`/details/${entry.Id}`)}?;镜膜?、ルーティング ライブラリのプッシュ メソッドを呼び出してユーザーを詳細(xì)ビューに移動しますが、問題のアイテムに対応する Id パラメーターを渡します。

ユーザーが実行できるもう 1 つのアクションは、リストから項目を削除することです。対応するボタンをクリックすると、確認(rèn)ポップアップが表示され、showAlert 関數(shù)が呼び出されます。この関數(shù)は、実際には sweetalert2 ライブラリの抽象化レイヤーである showWarning を呼び出します (sweetalert2 ライブラリを呼び出すすべての関數(shù)は、frontend/src/lib/popups/popups.ts にあります)。ユーザーが削除アクションを確認(rèn)すると、DeleteEntry バインディングが呼び出され (DB から削除するため)、返された Promise が解決されると、deleteItem が呼び出されます (エントリ狀態(tài)に格納されている配列から削除するため)。 :

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

ホーム ビューの他のコンポーネント (BottomActions) は非常に単純です。props を受け取らず、ユーザーをさまざまなビュー (設(shè)定、バージョン情報、または追加パスワード) にリダイレクトすることに限定されています。

AddPassword ビューと EditPassword ビューは非常によく似たロジックを共有し、Login ビューにも似ています。どちらの場合も、ユーザーはテキスト入力で入力した內(nèi)容の先頭と末尾にスペースを入力することはできません。また、パスワードの長さは少なくとも 6 文字の ASCII 文字である必要があるというログイン ビューと同じポリシーに従います?;镜膜恕ⅳ饯欷椁騾^(qū)別するのは、実行する必要があるアクションに関連する Wails が生成したリンクを呼び出すことです。

/* main.ts */

import { mount } from 'svelte'
import './style.css'
import App from './App.svelte'
import { addMessages, init } from "svelte-i18n"; // ? ?
import en from './locales/en.json'; // ? ?
import es from './locales/es.json'; // ? ?

addMessages('en', en); // ? ?
addMessages('es', es); // ? ?

init({
  fallbackLocale: 'en', // ? ?
  initialLocale: 'en', // ? ?
});

const app = mount(App, {
  target: document.getElementById('app')!,
})

export default app

やや複雑なもう 1 つのビューは、[設(shè)定] です。これには、親コンポーネント (設(shè)定) から props 言語名を受け取る言語コンポーネントがあります:

/* frontend/src/locales/en.json */

{
    "language": "Language",
    "app_title": "Nu-i uita ? minimalist password store",
    "select_directory": "Select the directory where to save the data export",
    "select_file": "Select the backup file to import",
    "master_password": "Master Password ?",
    "generate": "Generate",
    "insert": "Insert",
    "login": "Login",
    ...
}


/* frontend/src/locales/es.json */

{
    "language": "Idioma",
    "app_title": "Nu-i uita ? almacén de contrase?as minimalista",
    "select_directory": "Selecciona el directorio donde guardar los datos exportados",
    "select_file": "Selecciona el archivo de respaldo que deseas importar",
    "master_password": "Contrase?a Maestra ?",
    "generate": "Generar",
    "insert": "Insertar",
    "login": "Inciar sesión",
    ...
}

このコンポーネントの HTML は、ユーザーの言語選択を処理する?yún)g一の select です。 onchange イベントで、次の 3 つのことを行う関數(shù) (handleChange) を受け取ります。

  • svelte-i18n ライブラリを使用してフロントエンドの言語を設(shè)定します
  • イベント ("change_titles") を発行し、Wails ランタイムがアプリケーションのタイトル バーのタイトルと、関連する ディレクトリの選択 および ファイルの選択 ダイアログ ボックスのタイトルを変更するようにします。前のアクションへ
  • ユーザーが選択した言語を DB に保存し、次回アプリケーションを起動したときにその言語で構(gòu)成された狀態(tài)で開きます。

[設(shè)定] ビューに戻ると、その操作全體がバックエンドとの間で送受信される一連のイベントによって制御されます。最も単純なのは [終了] ボタンです。ユーザーがボタンをクリックすると、終了イベントがトリガーされてバックエンドでリッスンされ、アプリケーションが終了します (onclick={() => EventsEmit("quit")})。 ヒントは、すでに説明したように、Escape キー (ショートカット) が同じアクションを?qū)g行することをユーザーに通知します。

リセット ボタンは、ポップアップ ウィンドウを表示する関數(shù)を呼び出します。

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

ユーザーがアクションを受け入れると、Drop バインディングが呼び出され、DB 內(nèi)のすべての コレクション がクリーンアップされ、返された Promise が解決されると、ユーザーがログイン ビューに送信され、次のことが表示されます。アクションの成功を示すモーダル。

殘りの 2 つのアクションは互いに似ているので、データのインポートを見てみましょう。

ユーザーが対応するボタンをクリックすると、イベントが発行され (onclick={() => EventsEmit("import_data")})、バックエンドでリッスンされます。受信すると、ネイティブの ファイルの選択 ダイアログ ボックスが開き、ユーザーがバックアップ ファイルを選択できるようになります。ユーザーがファイルを選択すると、パス (fileLocation) を含む変數(shù)には空の文字列が含まれないため、バックエンドでイベント (「enter_password」) がトリガーされ、フロントエンドでこのイベントがリッスンされ、次に表示されます。エクスポート時に使用されたマスターパスワードを?qū)い亭胄陇筏ぅ荪氓抓ⅴ氓抓Ε%螗丧Δ硎兢丹欷蓼?。ここでも、フロントエンドは、ユーザーが入力したマスター パスワードを運ぶ別のイベント (「パスワード」) を発行します。この新しいイベントは、バックエンドで受信されると、DB パッケージの ImportDump メソッドを?qū)g行します。このメソッドは、ユーザーが選択したバックアップ ファイルから DB 內(nèi)のデータを読み取り、復(fù)元する作業(yè)を?qū)g行します。その結(jié)果、新しいイベント (「imported_data」) が発行され、実行の結(jié)果 (成功または失敗) が添付データとして送信されます。フロントエンドはイベントを受信すると、次の 2 つのタスクのみを?qū)g行する必要があります:

  • 結(jié)果が成功した場合は、バックアップ ファイルに保存された言語を設(shè)定し、アクションの成功を示すモーダルを表示します
  • 何らかの理由でインポートを?qū)g行できなかった場合は、エラーとその原因を表示します。

これらはすべて、言葉で説明するよりもコード ロジックで確認(rèn)する方がはるかに簡単です ?:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│?? ├── App.svelte
│?? ├── assets
│?? │?? ├── fonts
│?? │?? │?? ├── nunito-v16-latin-regular.woff2
│?? │?? │?? └── OFL.txt
│?? │?? └── images
│?? │??     └── logo-universal.png
│?? ├── lib
│?? │?? ├── BackBtn.svelte
│?? │?? ├── BottomActions.svelte
│?? │?? ├── EditActions.svelte
│?? │?? ├── EntriesList.svelte
│?? │?? ├── Language.svelte
│?? │?? ├── popups
│?? │?? │?? ├── alert-icons.ts
│?? │?? │?? └── popups.ts
│?? │?? ├── ShowPasswordBtn.svelte
│?? │?? └── TopActions.svelte
│?? ├── locales
│?? │?? ├── en.json
│?? │?? └── es.json
│?? ├── main.ts
│?? ├── pages
│?? │?? ├── About.svelte
│?? │?? ├── AddPassword.svelte
│?? │?? ├── Details.svelte
│?? │?? ├── EditPassword.svelte
│?? │?? ├── Home.svelte
│?? │?? ├── Login.svelte
│?? │?? └── Settings.svelte
│?? ├── style.css
│?? └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │?? ├── main
    │?? │?? ├── App.d.ts
    │?? │?? └── App.js
    │?? └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...

フロントエンド (EventsOn) にリスナーを登録する Wails ランタイム関數(shù)は関數(shù)を返し、呼び出されたときにそのリスナーをキャンセルすることに言及する価値があります。コンポーネントが破棄されたときに、前述のリスナーをキャンセルすると便利です。 React と同様に、onMount フックは、リスナーにクリーンアップ関數(shù)を返させることで、リスナーを「クリーンアップ」できます。この場合、別個に保存するように予防策を講じた EventsOn によって返されるすべての関數(shù)を呼び出します。変數(shù):

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;

アプリケーションのフロントエンド部分のレビューを終えるには、About コンポーネントについて少し説明するだけです。通常のアバウト表示のように、アプリケーションに関する情報の表示に限定されているため、これにはほとんどロジックがありません。ただし、ご覧のとおり、ビューにはアプリケーション リポジトリへのリンクが表示されていることに注意してください。明らかに、通常の Web ページでは、アンカー タグ () によって対応するリンクに移動しますが、デスクトップ アプリケーションでは、Wails の実行時にこのための特定の関數(shù) (BrowserOpenURL) がなければ、これは起こりません。 :

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

これにより、バイナリが build/bin フォルダーにビルドされます。ただし、他のビルド オプションを選択したり、クロスコンパイルを?qū)g行したりするには、Wails CLI のドキュメントを參照することをお勧めします。

このアプリケーションについては、このシリーズの最初の部分ですでに述べたと思いますが、Windows と Linux のコンパイルにのみ焦點を當(dāng)ててきました。これらのタスク (テストのため反復(fù)的です) を快適な方法で実行するために、いくつかの小さなスクリプトと、それらを「調(diào)整」する Makefile を作成しました。

make create-bundles コマンドは、Linux バージョンの場合、アプリケーションを含む .tar.xz 圧縮ファイルと、実行可能ファイルをインストールする「インストーラー」として機能する Makefile、スタート メニュー と対応するアプリケーション アイコン。 Windows バージョンの場合、バイナリは dist/ というフォルダー內(nèi)の .zip として単純に圧縮されます。ただし、クロスプラットフォームの自動ビルドを希望する場合、Wails には、生成されたアーティファクトをアップロード (デフォルト オプション) できる Github Actions があります。リポジトリに追加します。

実行時に make create-bundles コマンドを使用すると、Wails コマンド wails build -clean -upx (Linux の場合) または wails build -skipbindings -s -platform windows/amd64 - が呼び出されることに注意してください。 upx (Windows の場合)。 -upx フラグは、コンピューターにインストールされている

UPX ユーティリティを使用したバイナリの圧縮を指します。実行可能ファイルのサイズが小さい秘密の一部は、このユーティリティが実行する素晴らしい圧縮ジョブによるものです。

最後に、ビルド スクリプトによって現(xiàn)在のリポジトリ タグが About ビューに自動的に追加され、ビルド後にその値がデフォルト (DEV_VERSION) に復(fù)元されることに注意してください。

ふぅ!この2記事は思ったより長くなってしまいました!しかし、これらを気に入っていただければ幸いです。そして何よりも、新しいプロジェクトを考えるのに役立つことを願っています。プログラミングで何かを?qū)Wぶことは、このように機能します…

すべてのアプリケーション コードはこの GitHub リポジトリにあることに注意してください。

また他の投稿でお會いしましょう。コーディングを楽しんでください?!!

以上がシンプルなパスワード マネージャー デスクトップ アプリ: Golang の Wails フレームワークへの進(jìn)出 (パート 2)の詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國語 Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中國語版

SublimeText3 中國語版

中國語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Web APIのGolangとPythonのパフォーマンスの違いを理解する Web APIのGolangとPythonのパフォーマンスの違いを理解する Jul 03, 2025 am 02:40 AM

Golangofferssuperiorporformance、nativeconconcurrencyviagoroutines、および効率的なresourceusage、makingitidealforhigh-raffic、low-latencyapis;

Golang Frontendまたはバックエンドです Golang Frontendまたはバックエンドです Jul 08, 2025 am 01:44 AM

Golangは主にバックエンド開発に使用されますが、フロントエンドフィールドで間接的な役割を果たすこともできます。その設(shè)計目標(biāo)は、高性能、同時処理、システムレベルのプログラミングに焦點を當(dāng)てており、APIサーバー、マイクロサービス、分散システム、データベース操作、CLIツールなどのバックエンドアプリケーションの構(gòu)築に適しています。 GolangはWebフロントエンドの主流言語ではありませんが、Gopherjsを介してJavaScriptにコンパイルしたり、Tinygoを介してWebAssemblyで実行したり、テンプレートエンジンを備えたHTMLページを生成してフロントエンド開発に參加できます。ただし、最新のフロントエンド開発は、JavaScript/TypeScriptとそのエコシステムに依存する必要があります。したがって、Golangは、コアとして高性能バックエンドを備えたテクノロジースタック選択により適しています。

GolangでGraphQL APIを構(gòu)築する方法 GolangでGraphQL APIを構(gòu)築する方法 Jul 08, 2025 am 01:03 AM

GOでGraphQlapiを構(gòu)築するには、GQLGenライブラリを使用して開発効率を向上させることをお勧めします。 1.最初に、スキーマに基づいた自動コード生成をサポートするGQLGENなどの適切なライブラリを選択します。 2。次に、graphqlschemaを定義し、投稿の種類やクエリメソッドの定義など、API構(gòu)造とクエリポータルを説明します。 3。次に、プロジェクトを初期化し、基本コードを生成して、リゾルバにビジネスロジックを?qū)g裝します。 4.最後に、graphqlhandlerをhttpserverに接続し、組み込みの遊び場を介してAPIをテストします。メモには、プロジェクトのメンテナンスを確保するためのフィールドネーミング仕様、エラー処理、パフォーマンスの最適化、セキュリティ設(shè)定が含まれます

GOのインストール方法 GOのインストール方法 Jul 09, 2025 am 02:37 AM

GOをインストールするための鍵は、正しいバージョンを選択し、環(huán)境変數(shù)を構(gòu)成し、インストールを検証することです。 1.公式Webサイトにアクセスして、対応するシステムのインストールパッケージをダウンロードします。 Windowsは.msiファイルを使用し、macosは.pkgファイルを使用し、Linuxは.tar.gzファイルを使用し、 /usr /localディレクトリに解凍します。 2.環(huán)境変數(shù)を構(gòu)成し、linux/macOSで?/.bashrcまたは?/.zshrcを編集してパスとgopathを追加し、Windowsがシステムプロパティに移動するパスを設(shè)定します。 3.政府コマンドを使用してインストールを確認(rèn)し、テストプログラムを?qū)g行してhello.goを?qū)g行して、編集と実行が正常であることを確認(rèn)します。プロセス全體のパス設(shè)定とループ

リソース消費(CPU/メモリ)典型的なGolang vs Python Webサービスのベンチマーク リソース消費(CPU/メモリ)典型的なGolang vs Python Webサービスのベンチマーク Jul 03, 2025 am 02:38 AM

Golangは通常、Webサービスを構(gòu)築するときにPythonよりもCPUとメモリを消費します。 1. GolangのGoroutineモデルは、スケジューリングに効率的であり、強力なリクエスト処理機能を備えており、CPUの使用量が少ない。 2。GOはネイティブコードにコンパイルされ、ランタイム中に仮想マシンに依存せず、メモリの使用量が小さくなります。 3. Pythonは、GILと解釈実行メカニズムのために、同時シナリオでより大きなCPUとメモリオーバーヘッドを持っています。 4. Pythonには高い開発効率と豊富なエコシステムがありますが、低リソースを消費します。これは、並行性要件が低いシナリオに適しています。

GO SYNC.WAITGROUPの例 GO SYNC.WAITGROUPの例 Jul 09, 2025 am 01:48 AM

sync.waitgroupは、ゴルチンのグループがタスクを完了するのを待つために使用されます。そのコアは、3つの方法で協(xié)力することです。追加、完了、待機です。 1.ADD(n)待機するゴルチンの數(shù)を設(shè)定します。 2.done()は各ゴルチンの端で呼び出され、カウントは1つ減少します。 3.wait()すべてのタスクが完了するまでメインコルーチンをブロックします。使用する場合は、注意してください。Goroutineの外部で追加する必要があります。重複を避け、Donが呼び出されていることを確認(rèn)してください。 Deferで使用することをお勧めします。これは、Webページの同時クロール、バッチデータ処理、その他のシナリオで一般的であり、並行性プロセスを効果的に制御できます。

埋め込みパッケージチュートリアルに移動します 埋め込みパッケージチュートリアルに移動します Jul 09, 2025 am 02:46 AM

Goの埋め込みパッケージを使用すると、靜的リソースをバイナリに簡単に埋め込み、Webサービスに適しており、HTML、CSS、寫真、その他のファイルをパッケージ化できます。 1。追加する埋め込みリソースを宣言します// go:embed comment hello.txtを埋め込むなど、変數(shù)の前に埋め込みます。 2。static/*などのディレクトリ全體に埋め込み、embed.fsを介してマルチファイルパッケージを?qū)g現(xiàn)できます。 3.効率を改善するために、ビルドタグまたは環(huán)境変數(shù)を介してディスクロードモードを切り替えることをお勧めします。 4.パスの精度、ファイルサイズの制限、埋め込みリソースの読み取り専用特性に注意してください。埋め込みの合理的な使用は、展開を簡素化し、プロジェクト構(gòu)造を最適化することができます。

コードの読みやすさと保守性の評価:Golang vs Pythonの視點 コードの読みやすさと保守性の評価:Golang vs Pythonの視點 Jul 03, 2025 am 02:40 AM

COOSIONGOOSIONGOOSIONGOOSIONGOOSIONGOOSIONGONDPYTHONFORCODEREADANIVERATIONALIGHT、theSecisionHingSonteampriolities.1.GolangOfferStrictStrictConsinceWithMinimal、意見を述べたsyntaxandaxandaxandaxandisinglikelikelikegofmt、enuringuniformcodestylecection.2.pythertection.2

See all articles