Vue3.js(Tauri vue3 vuetity) から始めるディスクトップアプリ#3 [TautiAPIを使ってみよう!]
はじめに
Tauriには、前回説明したcommandsを利用した、Rust関数を呼ぶ以外にTautiAPIとして、フロント側よりOS機能を簡単に利用できるようにAPIが用意されています。
APIの種類
app cli clipboard dialog event fs globalShortcut http mocks
notification os path process shell tauri updater window など
今回は、windowを操作するAPIと少し毛色の異なるeventを使ってみます。
TauriAPIを利用するための準備
windowAPIを利用するためには、まず利用することを許可しなければならないです。
"tauri": {
"allowlist": {
"window": {
"all": true, // enable all window APIs
"create": true, // enable window creation
"center": true,
"requestUserAttention": true,
"setResizable": true,
"setTitle": true,
"maximize": true,
"unmaximize": true,
"minimize": true,
"unminimize": true,
"show": true,
"hide": true,
"close": true,
"setDecorations": true,
"setAlwaysOnTop": true,
"setSize": true,
"setMinSize": true,
"setMaxSize": true,
"setPosition": true,
"setFullscreen": true,
"setFocus": true,
"setIcon": true,
"setSkipTaskbar": true,
"setCursorGrab": true,
"setCursorVisible": true,
"setCursorIcon": true,
"setCursorPosition": true,
"setIgnoreCursorEvents": true,
"startDragging": true,
"print": true
}
}
}
}
本来は必要に応じてtrueを設定すべきですが、所詮Window操作なので今回は、 "all": true とすべて許可と設定します。
下記のように修正しました。
~
"tauri": {
"allowlist": {
"all": false,
+ "window": {
+ "all": true // enable all window APIs
+ }
},
~
WindowAPIの利用
利用するための準備ができたので、使ってみます。
Window生成時にセットで利用しそうなAPIをピックアップしました。
center(): Promise<void> ウィンドウを中央に配置します。
maximize(): Promise<void> ウィンドウを最大化する。
setFocus(): Promise<void> ウィンドウを最前面に移動し、フォーカスを合わせる。
Vue Createdで呼びます。
created(){
console.log("Start!!")
this.WindowAPI();
}
import { appWindow } from "@tauri-apps/api/window";
~
methods: {
async WindowAPI() {
await appWindow.center();
await appWindow.maximize();
await appWindow.setFocus();
},
~
promise型なので、awaitで呼びます。画面が最大化で表示されればOKです。
Eventの利用
バックエンドからのイベントを検知します。
イベント種類は、下記の通りです。
Name | Type | コメント |
---|---|---|
CHECK_UPDATE | "tauri://update" | |
DOWNLOAD_PROGRESS | "tauri://update-download-progress" | |
INSTALL_UPDATE | "tauri://update-install" | |
MENU | "tauri://menu" | |
STATUS_UPDATE | "tauri://update-status" | |
UPDATE_AVAILABLE | "tauri://update-available" | |
WINDOW_BLUR | "tauri://blur" | |
WINDOW_CLOSE_REQUESTED | "tauri://close-requested" | |
WINDOW_CREATED | "tauri://window-created" | |
WINDOW_DESTROYED | "tauri://destroyed" | |
WINDOW_FILE_DROP | "tauri://file-drop" | |
WINDOW_FILE_DROP_CANCELLED | "tauri://file-drop-cancelled" | |
WINDOW_FILE_DROP_HOVER | "tauri://file-drop-hover" | |
WINDOW_FOCUS | "tauri://focus" | |
WINDOW_MOVED | "tauri://move" | 左上の座標 |
WINDOW_RESIZED | "tauri://resize" | Windowのサイズ |
WINDOW_SCALE_FACTOR_CHANGED | "tauri://scale-change | |
WINDOW_THEME_CHANGED | "tauri://theme-changed" |
今回は、WINDOW_MOVEDとWINDOW_RESIZEDを拾ってみます。
created(){
console.log("Start!!")
this.WindowAPI();
+ this.Event();
}
```ts:app.vue
import { appWindow } from "@tauri-apps/api/window";
~
export type move = {
x: number;
y: number;
};
export type resize = {
height: number;
width: number;
};
methods: {
~
Event() {
appWindow.listen("tauri://move", ({ event, payload}) => {
let move : move = payload as move;
console.log('Potision x=' , move.x , " y=", move.y );
});
appWindow.listen("tauri://resize",({ event, payload}) => {
let resize : resize = payload as resize;
console.log('WindowSize x=' ,resize.height , " y=", resize.width );
});
~
listenでtauri://moveを待ちます。
発火されれば、event に Event名 payloadにデータが入ります。
おわりに
このEventシステムは、electronよりシンプルで直感的で好感が持てます。
複雑なコーティング・省略しすぎるコーティング 自分は、大っ嫌いです。
Simple is Best だれかマイクロソフトに教えてあげてください。
最後に全コードを載せます。
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"build": {
"beforeBuildCommand": "yarn build",
"beforeDevCommand": "yarn dev",
"devPath": "http://localhost:5173",
"distDir": "../dist"
},
"package": {
"productName": "myproject",
"version": "0.1.0"
},
"tauri": {
"allowlist": {
"all": false,
"window": {
"all": true
}
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.tauri.dev",
"longDescription": "",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "myproject",
"width": 800
}
]
}
}
<template>
<div class="divInput" style="max-width: 400px">
<label >{{ textMsg }}</label>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { invoke } from '@tauri-apps/api'
import { appWindow } from "@tauri-apps/api/window";
//Dataオブジェクト
export type DataType = {
text: string;
};
export type move = {
x: number;
y: number;
};
export type resize = {
height: number;
width: number;
};
export default defineComponent({
name: 'App',
components: {},
data(): DataType {
return {
//nameの初期化
text: '',
};
},
computed: {
textMsg(){
invoke('greet',{name: "World"})
.then((response) => { if (typeof response === 'string'){
this.text = response;
}else{
console.log(response)
this.text = 'Error';
}
})
return this.text;
},
},
methods: {
async WindowAPI() {
await appWindow.center();
await appWindow.maximize();
await appWindow.setFocus();
},
Event() {
appWindow.listen("tauri://move", ({ event, payload}) => {
let move : move = payload as move;
console.log('Potision x=' , move.x , " y=", move.y );
});
appWindow.listen("tauri://resize",({ event, payload}) => {
let resize : resize = payload as resize;
console.log('WindowSize x=' ,resize.height , " y=", resize.width );
});
}
},
watch: {},
created(){
console.log("Start!!")
this.WindowAPI();
this.Event();
}
});
</script>
<style scoped>
</style>
Discussion