😽

Vue3.js(Tauri vue3 vuetity) から始めるディスクトップアプリ#5 [Vuetify3 Themesを使ってみよう]

2022/11/29に公開

はじめに

かっこいいディスクトップアプリには必須となるテーマを使ってみます。
https://next.vuetifyjs.com/en/features/theme/#theme-configuration
ダークとライトの2種類がVuetify3標準となっているみたいです。

デフォルトの設定

一応、参考のためデフォルトの設定をしますが、しなくてもOKです。(アプリから変更するため)

vuetify.js
// Styles
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'

// Composables
import { createVuetify } from 'vuetify'
import { createApp } from 'vue'

// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
export default createVuetify({
+  theme: {
+    defaultTheme : 'dark'
+
+  },
})

テンプレート構文

v-app タグに設定します。theme を 'dark'や'light'にすることにより切り替わります。

App.vue
<template>
+ <v-app :theme="theme">
+   <v-main>
      <div class="divInput" style="max-width: 400px">
        <v-label >{{ textMsg }}</v-label><br/>
      </div>
+     <v-btn @click="toggleTheme" >
        Button
      </v-btn>
+   </v-main>
+ </v-app>
</template>

ボタン押下で切り替わるようにします。

App.vue
  methods: {
    toggleTheme() {
      this.theme = (this.theme === 'light' ?  'dark' : 'light')
    },

さいごに

すごく容易にできました。
TauriAPIを使ってWindowのテーマと連動も容易にできそうだし、自作テーマに作れそうなので、デザインの幅が広がります。

全コード

App.vue
<template>
  <v-app :theme="theme">
    <v-main>
      <div class="divInput" style="max-width: 400px">
        <v-label >{{ textMsg }}</v-label><br/>
      </div>
      <v-btn @click="toggleTheme" >
        Button
      </v-btn>
    </v-main>
  </v-app>
</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;
  theme :string ;
};
//Dataオブジェクト
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: '',
      theme: 'dark'
    };
  },
  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: {
    toggleTheme() {
      this.theme = (this.theme === 'light' ?  'dark' : 'light')
    },
    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