Vue3とElectronを使ったデスクトップアプリケーションの詳しい説明

Vue3とElectronを使ったデスクトップアプリケーションの詳しい説明

個人的なエッセイを記録するために、最近、markdown-it をベースにしたmarkdownエディターVueコンポーネント v-md-editor を使用したLaravelVue 3.0でブログ システムを構築しました。 markdownで書くときに使うととても便利だと思います。その後、私はこのコンポーネントをベースにしたmarkdownデスクトップ アプリケーションを Electron を使用して実装するというアイデアを思いつきました。これは私にとっても日常的な使用に適した選択肢です。

余談ですが、 VS Code はElectronで開発されたデスクトップ アプリケーションです。モバイル開発を除き、現在は他のすべての開発にVS Codeを使用しています。さまざまなプラグインを開発するのに非常に便利です。

次に、この機能を実装する手順を順を追って説明します。

Vue CLIはVueプロジェクトを構築します

選択したディレクトリでvue create electron-vue3-mark-downを実行します。

カスタムテンプレートを選択します(デフォルトのVue 3テンプレートを選択できます)

Vue3TypeScriptを選択し、プロジェクトに応じて他のオプションを選択します。

vue3 + タイプスクリプト

効果を確認するにはnpm run serveを実行します。

効果

Vue プロジェクトをマークダウンエディターに変換

v-md-editorをインストールするには、 npm i @kangc/v-md-editor@next -Sを実行します。

TypeScript型定義ファイルを追加する

v-md-editorライブラリにはTypeScript型定義ファイルがないため、 shims-vue.d.tsファイルの直後に追加しました。もちろん、新しいファイルを作成して宣言を追加することもできます ( tsconfig.json がこのファイルを見つけられる限り)。

モジュール「*.vue」を宣言します。
  "vue" から DefineComponent 型をインポートします。
  const コンポーネント: DefineComponent<{}, {}, any>;
  デフォルトコンポーネントをエクスポートします。
}

<!-- 追加されたコンテンツ -->
モジュール「@kangc/v-md-editor/lib/theme/vuepress.js」を宣言します。
モジュール "@kangc/v-md-editor/lib/plugins/copy-code/index" を宣言します。
モジュール「@kangc/v-md-editor/lib/plugins/line-number/index」を宣言します。
モジュール "@kangc/v-md-editor" を宣言します。
モジュール「prismjs」を宣言します。

App.vueの変換

<テンプレート>
  <div>
    <v-md-editor v-model="content" height="100vh"></v-md-editor>
  </div>
</テンプレート>

<script lang="ts">
// エディター import VMdEditor from "@kangc/v-md-editor";
"@kangc/v-md-editor/lib/style/base-editor.css" をインポートします。
「@kangc/v-md-editor/lib/theme/vuepress.js」からvuepressをインポートします。
"@kangc/v-md-editor/lib/theme/style/vuepress.css" をインポートします。
// ハイライト import Prism from "prismjs";
「prismjs/components/prism-json」をインポートします。
「prismjs/components/prism-dart」をインポートします。
「prismjs/components/prism-c」をインポートします。
「prismjs/components/prism-swift」をインポートします。
「prismjs/components/prism-kotlin」をインポートします。
「prismjs/components/prism-java」をインポートします。

// コードをすばやくコピーします import createCopyCodePlugin from "@kangc/v-md-editor/lib/plugins/copy-code/index";
"@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css" をインポートします。
// 行番号 import createLineNumbertPlugin from "@kangc/v-md-editor/lib/plugins/line-number/index";
VMdEditor.use(vuepress, {
  プリズム、
})
  .use(コピーコードプラグインの作成())
  .use(createLineNumbertPlugin());

「vue」からdefineComponent、refをインポートします。
エクスポートデフォルトdefineComponent({
  名前:「アプリ」、
  コンポーネント: { VMdEditor },
  設定() {
    定数コンテンツ = ref("");

    {コンテンツ}を返します。
  },
});
</スクリプト>

<スタイル>
/* いくつかのボタンを削除します */
.v-md-icon-save、
.v-md-アイコン-フルスクリーン {
  表示: なし;
}
</スタイル>

このファイルも非常にシンプルです。ページ全体がエディタです<v-md-editor v-model="content" height="100vh"></v-md-editor> 。このマークダウンエディタには、ハイライト、コード行番号表示、コードコピーボタンなどのプラグインがあります。もちろん、他のプラグインを追加してこのマークダウンエディタの機能を充実させるとより便利です。

効果は以下のとおりです

エディター効果

Vue CLI プラグイン Electron ビルダー

Vite 2.0 を使用してElectronプロジェクトを構築しようとしましたが、 ViteElectronをうまく組み合わせた同様のツールが見つからなかったため、 Vite 2.0の誘惑をあきらめました。何かおすすめがあれば、ぜひ共有してください。

インストールにはvue add electron-builderを使用します。私はElectronの最新バージョン13.0.0を選択しました。

私はいつも一番高いバージョンを選びます。実はこのバージョンには落とし穴があります。この落とし穴については後ほど紹介しようと思います(笑)。

効果

多くの新しい依存ライブラリが追加され、 background.tsファイルが追加されていることがわかります。簡単に説明すると、このファイルはメインスレッドで実行され、他のページはレンダリングスレッドで実行されます。レンダリング スレッドには多くの制限があり、一部の関数はメイン スレッドでのみ実行できますが、ここでは詳しく説明しません。

効果を確認するにはnpm run electron:serveを実行します。

効果

この時点で、デスクトップ アプリケーションの効果を確認でき、Vue コードを変更しながら、デスクトップ アプリケーションでも変更された効果をリアルタイムで確認できます。

最適化

全画面表示を開始

紹介画面

「electron」から { screen } をインポートします。

ウィンドウを作成するときに画面サイズを設定する

<!-- 背景.ts -->
非同期関数createWindow() {
  const { 幅、高さ } = screen.getPrimaryDisplay().workAreaSize;
  const win = 新しいブラウザウィンドウ({
    幅、
    身長、
    // 省略...
  });
    // 省略...
}

こうすることで、アプリケーションは起動時に全画面で表示されます。

メニューバーを変更する

メニューバーを定義する

<!-- 背景.ts -->

const テンプレート: Array<MenuItemConstructorOptions> = [
  {
    ラベル: "MarkDown",
    サブメニュー: [
      {
        ラベル: "About",
        アクセラレータ: "CmdOrCtrl+W",
        役割: "について",
      },
      {
        ラベル: "プログラムを終了",
        アクセラレータ: "CmdOrCtrl+Q",
        役割: 「終了」、
      },
    ]、
  },
  {
    ラベル: "ファイル",
    サブメニュー: [
      {
        ラベル: "ファイルを開く",
        アクセラレータ: "CmdOrCtrl+O",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          _event: キーボードイベント
        ) => {
            // TODO: ファイルを開く},
      },
      {
        ラベル: 「ストレージ」、
        アクセラレータ: "CmdOrCtrl+S",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          _event: キーボードイベント
        ) => {
          //TODO: コンテンツを保存する},
      },
    ]、
  },
  {
    ラベル: "編集",
    サブメニュー: [
      {
        ラベル: 「取り消し」、
        アクセラレータ: "CmdOrCtrl+Z",
        役割: 「元に戻す」、
      },
      {
        ラベル: 「やり直し」、
        アクセラレータ: "Shift+CmdOrCtrl+Z",
        役割: 「やり直し」、
      },
      {
        タイプ:「セパレータ」、
      },
      {
        ラベル: 「カット」、
        アクセラレータ: "CmdOrCtrl+X",
        役割: 「カット」、
      },
      {
        ラベル: "コピー",
        アクセラレータ: "CmdOrCtrl+C",
        役割: "コピー"、
      },
      {
        ラベル:「貼り付け」、
        アクセラレータ: "CmdOrCtrl+V",
        役割: 「貼り付け」、
      },
    ]、
  },
  {
    ラベル: "ウィンドウ",
    役割: "ウィンドウ"、
    サブメニュー: [
      {
        ラベル: 「最小化」、
        アクセラレータ: "CmdOrCtrl+M",
        役割: 「最小化」、
      },
      {
        ラベル:「最大化」、
        アクセラレータ: "CmdOrCtrl+M",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          _event: キーボードイベント
        ) => {
          if (focusedWindow) {
            フォーカスウィンドウを最大化します。
          }
        },
      },
      {
        タイプ:「セパレータ」、
      },
      {
        ラベル: 「全画面に切り替える」、
        アクセラレータ: (function () {
          プロセスプラットフォームが「ダーウィン」の場合
            「Ctrl+Command+F」を返します。
          } それ以外 {
            「F11」を返します。
          }
        })(),
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          // eslint 次の行を無効にする @typescript-eslint/未使用変数なし
          _event: キーボードイベント
        ) => {
          if (focusedWindow) {
            focusWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        },
      },
    ]、
  },
  {
    ラベル: "ヘルプ",
    役割: "ヘルプ"、
    サブメニュー: [
      {
        ラベル: "詳細を見る",
        クリック: 関数 () {
          シェルを外部から開きます("http://electron.atom.io");
        },
      },
    ]、
  },
];

定義方法の詳細については、Electron メニューを参照してください。

ファイルのオープン保存はまだ実装されていませんが、後で実装される予定です。

メニューバーを設定する

"electron"から{Menu}をインポートします。
app.on("準備完了", 非同期() => {
  // 省略...
  // メニューを作成しますMenu.setApplicationMenu(Menu.buildFromTemplate(template));
});

readyフック関数でメニューを設定します。

効果

メニュー効果

エディターはmarkdonwファイルの内容を開きます

メインスレッドはファイルを選択し、ファイルパスをレンダリングスレッドに渡します。

<!-- 背景.ts -->
ダイアログ
  .showOpenDialog({
    プロパティ: ["openFile"],
    フィルター: [{ name: "カスタムファイルタイプ", 拡張子: ["md"] }],
  })
  .then((res) => {
    res && res["filePaths"].length > 0 の場合 {
      const filePath = res["filePaths"][0];
      // ファイルをレンダリングスレッドに渡す if (focusedWindow) {
        focusedWindow.webContents.send("open-file-path", filePath);
      }
    }
  })
  .catch((エラー) => {
    コンソールログ(エラー);
  });

showOpenDialogはファイルを開くメソッドです。ここでは md ファイルのみを開くように指定します。

ファイル パスを取得したら、 focusedWindow.webContents.send("open-file-path", filePath);メソッドを通じて、ファイル パスをレンダリング スレッドに渡します。

レンダリングスレッドはファイルパスを取得し、ファイルの内容を読み取り、それをマークダウンエディタに割り当てます。

<!-- App.vue -->
「electron」から { ipcRenderer } をインポートします。
「fs」から{readFileSync}をインポートします。

エクスポートデフォルトdefineComponent({
  // 省略...
  設定() {
    定数コンテンツ = ref("");
    
    マウント時(() => {
      // 1.
      ipcRenderer.on("open-file-path", (e, filePath: 文字列) => {
        ファイルパス && ファイルパス.長さ > 0 の場合 {
          // 2.
          content.value = readFileSync(filePath).toString();
        }
      });
    });

    {コンテンツ}を返します。
  },
});

Vue がノードサポートを追加

<!-- vue.config.js -->
モジュール.エクスポート = {
  プラグインオプション: {
    電子ビルダー: {
      ノード統合: true、
    },
  },
};

効果

レンダリング

markdonwの内容をファイルに保存する

メインスレッドはレンダリングスレッドにエディタコンテンツを取得する要求を開始します。

<!-- background.js -->
if (focusedWindow) {
    focusedWindow.webContents.send("get-content", "");
}

レンダリングスレッドはエディターのコンテンツをメインスレッドに返します。

<!-- App.vue -->
マウント時(() => {
    ipcRenderer.on("コンテンツを取得", () => {
        ipcRenderer.send("save-content", content.value);
    });
});

メインスレッドはコンテンツを受け取り、ファイルに保存します

<!-- 背景.ts -->
// ファイルを保存 ipcMain.on("save-content", (event: unknown, content: string) => {
  開いたファイルの長さが0より大きい場合
    // ファイルに直接保存する try {
      開いたファイルの内容を書き込む。
      console.log("正常に保存しました");
    } キャッチ(エラー){
      console.log("保存に失敗しました");
    }
  } それ以外 {
    定数オプション = {
      タイトル:「ファイルを保存」、
      デフォルトパス: "new.md",
      フィルター: [{ name: "カスタムファイルタイプ", 拡張子: ["md"] }],
    };
    定数 focusWindow = BrowserWindow.getFocusedWindow();
    if (focusedWindow) {
      ダイアログ
        .showSaveDialog(フォーカスされたウィンドウ、オプション)
        .then((結果: Electron.SaveDialogReturnValue) => {
          if (結果.ファイルパス) {
            試す {
              writeFileSync(結果.filePath、コンテンツ);
              console.log("正常に保存されました");
              開いたファイル = result.filePath;
            } キャッチ(エラー){
              console.log("保存に失敗しました");
            }
          }
        })
        .catch((エラー) => {
          コンソール.log(エラー);
        });
    }
  }
});

効果

レンダリング

パック

アプリケーションの名前と画像を設定する

<!-- vue.config.js -->
モジュール.エクスポート = {
  プラグインオプション: {
    電子ビルダー: {
      ノード統合: true、
      // 追加された設定 builderOptions: {
        アプリID: "com.johnny.markdown", 
        productName: "JJMarkDown", // アプリケーション名 copyright: "Copyright © 2021", // 著作権声明 mac: {
          アイコン: "./public/icon.icns", // アイコン
        },
      },
    },
  },
};

icon.icns 生成用の 1024*1024 の画像を準備し、同じディレクトリにicons.iconsetという名前のフォルダーを作成します。

さまざまなサイズの画像ファイルを作成する

sips -z 16 16 icon.png -o icons.iconset/icon_16x16.png
sips -z 32 32 icon.png -o icons.iconset/[email protected]
sips -z 32 32 icon.png -o icons.iconset/icon_32x32.png
sips -z 64 64 icon.png -o icons.iconset/[email protected]
sips -z 128 128 icon.png -o icons.iconset/icon_128x128.png
sips -z 256 256 icon.png -o icons.iconset/[email protected]
sips -z 256 256 icon.png -o icons.iconset/icon_256x256.png
sips -z 512 512 icon.png -o icons.iconset/[email protected]
sips -z 512 512 icon.png -o icons.iconset/icon_512x512.png
sips -z 1024 1024 icon.png -o icons.iconset/[email protected]

icon.icnsという名前のアイコンファイルを取得します。

アイコンユーティリティ -c icns icons.iconset -o icon.icns

パック

npm 実行 electron:build

結果

ダメージ

取得した dmg ファイルは直接インストールして使用できます。

コード

<!-- 背景.ts -->
「厳密な使用」;

輸入 {
  アプリ、
  プロトコル、
  ブラウザウィンドウ、
  画面、
  メニュー、
  メニュー項目、
  シェル、
  ダイアログ、
  ipcメイン、
} から "electron" へ;
「electron/main」から KeyboardEvent と MenuItemConstructorOptions をインポートします。
「vue-cli-plugin-electron-builder/lib」から createProtocol をインポートします。
「electron-devtools-installer」から installExtension、{ VUEJS3_DEVTOOLS } をインポートします。
const isDevelopment = process.env.NODE_ENV !== "production";
「fs」から writeFileSync をインポートします。

開いたファイル = "";
// ファイルを保存 ipcMain.on("save-content", (event: unknown, content: string) => {
  開いたファイルの長さが0より大きい場合
    // ファイルに直接保存する try {
      開いたファイルの内容を書き込む。
      console.log("正常に保存しました");
    } キャッチ(エラー){
      console.log("保存に失敗しました");
    }
  } それ以外 {
    定数オプション = {
      タイトル:「ファイルを保存」、
      デフォルトパス: "new.md",
      フィルター: [{ name: "カスタムファイルタイプ", 拡張子: ["md"] }],
    };
    定数 focusWindow = BrowserWindow.getFocusedWindow();
    if (focusedWindow) {
      ダイアログ
        .showSaveDialog(フォーカスされたウィンドウ、オプション)
        .then((結果: Electron.SaveDialogReturnValue) => {
          if (結果.ファイルパス) {
            試す {
              writeFileSync(結果.filePath、コンテンツ);
              console.log("正常に保存しました");
              開いたファイル = result.filePath;
            } キャッチ(エラー){
              console.log("保存に失敗しました");
            }
          }
        })
        .catch((エラー) => {
          コンソール.log(エラー);
        });
    }
  }
});

const テンプレート: Array<MenuItemConstructorOptions> = [
  {
    ラベル: "MarkDown",
    サブメニュー: [
      {
        ラベル: "About",
        アクセラレータ: "CmdOrCtrl+W",
        役割: "について",
      },
      {
        ラベル: "プログラムを終了",
        アクセラレータ: "CmdOrCtrl+Q",
        役割: 「終了」、
      },
    ]、
  },
  {
    ラベル: "ファイル",
    サブメニュー: [
      {
        ラベル: "ファイルを開く",
        アクセラレータ: "CmdOrCtrl+O",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          // eslint 次の行を無効にする @typescript-eslint/未使用変数なし
          _event: キーボードイベント
        ) => {
          ダイアログ
            .showOpenDialog({
              プロパティ: ["openFile"],
              フィルター: [{ name: "カスタムファイルタイプ", 拡張子: ["md"] }],
            })
            .then((res) => {
              res && res["filePaths"].length > 0 の場合 {
                定数ファイルパス = res["ファイルパス"][0];
                // レンダリングスレッドにファイルを渡す if (focusedWindow) {
                  focusedWindow.webContents.send("open-file-path", filePath);
                  開かれたファイル = ファイルパス;
                }
              }
            })
            .catch((エラー) => {
              コンソールログ(エラー);
            });
        },
      },
      {
        ラベル: 「ストレージ」、
        アクセラレータ: "CmdOrCtrl+S",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          // eslint 次の行を無効にする @typescript-eslint/未使用変数なし
          _event: キーボードイベント
        ) => {
          if (focusedWindow) {
            focusedWindow.webContents.send("get-content", "");
          }
        },
      },
    ]、
  },
  {
    ラベル: "編集",
    サブメニュー: [
      {
        ラベル: 「取り消し」、
        アクセラレータ: "CmdOrCtrl+Z",
        役割: 「元に戻す」、
      },
      {
        ラベル: 「やり直し」、
        アクセラレータ: "Shift+CmdOrCtrl+Z",
        役割: 「やり直し」、
      },
      {
        タイプ:「セパレータ」、
      },
      {
        ラベル: 「カット」、
        アクセラレータ: "CmdOrCtrl+X",
        役割: 「カット」、
      },
      {
        ラベル: "コピー",
        アクセラレータ: "CmdOrCtrl+C",
        役割: "コピー"、
      },
      {
        ラベル:「貼り付け」、
        アクセラレータ: "CmdOrCtrl+V",
        役割: 「貼り付け」、
      },
    ]、
  },
  {
    ラベル: "ウィンドウ",
    役割: "ウィンドウ"、
    サブメニュー: [
      {
        ラベル: 「最小化」、
        アクセラレータ: "CmdOrCtrl+M",
        役割: 「最小化」、
      },
      {
        ラベル: "最大化",
        アクセラレータ: "CmdOrCtrl+M",
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          // eslint 次の行を無効にする @typescript-eslint/未使用変数なし
          _event: キーボードイベント
        ) => {
          if (focusedWindow) {
            フォーカスウィンドウを最大化します。
          }
        },
      },
      {
        タイプ:「セパレータ」、
      },
      {
        ラベル: 「全画面に切り替える」、
        アクセラレータ: (function () {
          プロセスプラットフォームが「ダーウィン」の場合
            「Ctrl+Command+F」を返します。
          } それ以外 {
            「F11」を返します。
          }
        })(),
        クリック: (
          項目: メニュー項目、
          focusedWindow: BrowserWindow | 未定義、
          // eslint 次の行を無効にする @typescript-eslint/未使用変数なし
          _event: キーボードイベント
        ) => {
          if (focusedWindow) {
            focusWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        },
      },
    ]、
  },
  {
    ラベル: "ヘルプ",
    役割: "ヘルプ"、
    サブメニュー: [
      {
        ラベル: "詳細を見る",
        クリック: 関数 () {
          シェルを外部から開きます("http://electron.atom.io");
        },
      },
    ]、
  },
];

プロトコル.registerSchemesAsPrivileged([
  { スキーム: "app"、権限: { secure: true、 standard: true } }、
]);

非同期関数createWindow() {
  const { 幅、高さ } = screen.getPrimaryDisplay().workAreaSize;
  const win = 新しいブラウザウィンドウ({
    幅、
    身長、
    ウェブ設定: {
      ノード統合: true、
      コンテキスト分離: false、
    },
  });

  プロセス環境のWEBPACK_DEV_SERVER_URLの場合{
    // 開発モードの場合は開発サーバーの URL をロードします
    win.loadURL(process.env.WEBPACK_DEV_SERVER_URL を文字列として) を待機します。
    プロセス環境がIS_TESTの場合、win.webContents.openDevTools();
  } それ以外 {
    プロトコルを作成します("アプリ");
    // 開発中でないときにindex.htmlをロードする
    win.loadURL("app://./index.html");
  }
}

// すべてのウィンドウが閉じられたら終了します。
app.on("ウィンドウがすべて閉じました", () => {
  // macOSではアプリケーションとそのメニューバーでよく使われる
  // ユーザーがCmd + Qで明示的に終了するまでアクティブのままにします
  プロセスプラットフォームが "darwin" の場合
    アプリを終了します。
  }
});

app.on("アクティブ化", () => {
  // macOSでは、アプリが終了してもウィンドウを再作成するのが一般的です。
  // ドックアイコンがクリックされ、他のウィンドウは開いていません。
  BrowserWindow.getAllWindows().length === 0 の場合、createWindow();
});

// このメソッドはElectronが終了したときに呼び出されます
// 初期化が完了し、ブラウザ ウィンドウを作成する準備が整いました。
// 一部の API はこのイベントが発生した後にのみ使用できます。
app.on("準備完了", 非同期() => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Vue Devtools をインストール
    試す {
      VUEJS3_DEVTOOLS のインストールを待機します。
    } キャッチ (e) {
      console.error("Vue Devtools のインストールに失敗しました:", e.toString());
    }
  }
  ウィンドウを作成します。
  // メニューを作成しますMenu.setApplicationMenu(Menu.buildFromTemplate(template));
});

// 開発モードで親プロセスからの要求に応じて正常に終了します。
if (isDevelopment) {
  プロセスプラットフォームが "win32" の場合
    process.on("メッセージ", (データ) => {
      if (data === "graceful-exit") {
        アプリを終了します。
      }
    });
  } それ以外 {
    プロセス.on("SIGTERM", () => {
      アプリを終了します。
    });
  }
}

デスクトップアプリケーションを実装するための Vue3 と Electron の詳細な説明については、この記事で終わります。Vue3 Electron デスクトップアプリケーションの関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vite+ElectronでVUE3デスクトップアプリケーションを素早く構築
  • Electron + Vueでデスクトップをパッケージ化する操作手順の詳細説明
  • vue + Electron でデスクトップ アプリケーションを作成するためのサンプル コード

<<:  MySQLのページング制限のパフォーマンス問題についての簡単な説明

>>:  Linux ログ表示方法 6 つのまとめ

推薦する

Docker Tomcat のアクセス インターフェイスが表示されないのはなぜですか?

質問:オリジン サーバーはターゲット リソースの表現を見つけることができないか、既存の表現を公開した...

MySQL における Decimal 型と Float Double 型の違い (詳細説明)

MySQL には、10 進数などの標準データ型だけでなく、float や double などの非標...

あなたのウェブサイトはIE8に適していますか?

オリンピック期間中にIE8ベータ2がリリースされ、英語版のリリースに合わせて中国語版も第一波でリリー...

Dockerはポートマッピングを設定しますが、ソリューションにアクセスできません

#docker ps チェック、すべてのポートがマップされています コンテナID イメージ コマンド...

MySQL 8の新機能におけるグローバルパラメータの永続性の詳細な説明

目次序文グローバルパラメータの永続性最後に要約する参考資料:序文2018 年に MySQL 8.0....

Linux LVM 論理ボリューム構成プロセス (作成、増加、削減、削除、アンインストール) の詳細な説明

Linux LVM論理ボリューム構成プロセスの詳細な説明多くの Linux ユーザーは、オペレーティ...

MySQL ステートメントの概要

目次1. データベースの使用を選択2. 情報を表示する3. テーブルを作成する4. データを挿入する...

上位Nを見つけるためのMySQLグループソートの詳細な説明

MySQLグループソートで上位Nを見つけるテーブル構造grp でグループ化し、num で並べ替えて、...

Linux でタスク用のカスタム システム トレイ インジケーターを作成する

システム トレイ アイコンは、今日でも魔法のような機能です。アイコンを右クリックして目的のアクション...

実用的なウェブオンラインツール12選

1.ファビコン.cc ico アイコンの Web サイトをオンラインで作成するには、画像をアップロー...

MySQL RouterはMySQLの読み取りと書き込みの分離を実装します

目次1. はじめに2. MySQLルーターを構成する2.1 MySQLルーターのインストール2.2 ...

MySQL スロークエリログの詳細な理解

目次スロークエリログとは何ですか?スロークエリを有効にする方法ログ分析ツール mysqldumpsh...

Centos7 で mysqldump を使用して MySQL データベースの毎日の自動バックアップを作成する

1. 要件:データベースのバックアップは、実稼働環境にとって特に重要です。データベースのバックアップ...

Web ページでパラメータ名によって ActiveX コントロールのプロパティに値を割り当てる例

コードをコピーコードは次のとおりです。 <HTML> <ヘッド> <T...