Open4

Tauri + Vue3

hirukiyohirukiyo

Startup

  • rust -> install済み
  • bunを使用 -> install済み
bunx create-tauri-app
  • log
bunx create-tauri-app
✔ Project name · tauri_example
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, bun)
✔ Choose your package manager · bun
✔ Choose your UI template · Vue - (https://vuejs.org/)
✔ Choose your UI flavor · TypeScript

Template created!

Your system is missing dependencies (or they do not exist in $PATH):
╭────────────────────┬──────────────────────────────────────────────────────────────────────────────────╮
│ webkit2gtk & rsvg2 │ Visit https://tauri.app/v1/guides/getting-started/prerequisites#setting-up-linux │
╰────────────────────┴──────────────────────────────────────────────────────────────────────────────────╯

Make sure you have installed the prerequisites for your OS: https://tauri.app/v1/guides/getting-started/prerequisites, then run:
  cd tauri_example
  bun install
  bun run tauri dev
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
    build-essential \
    curl \
    wget \
    file \
    libssl-dev \
    libgtk-3-dev \
    libayatana-appindicator3-dev \
    librsvg2-dev
  • log
sudo apt install libwebkit2gtk-4.0-dev \
    build-essential \
    curl \
    wget \
    file \
    libssl-dev \
    libgtk-3-dev \
    libayatana-appindicator3-dev \
    librsvg2-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
wget はすでに最新バージョン (1.21.2-2ubuntu1) です。
wget は手動でインストールしたと設定されました。
curl はすでに最新バージョン (7.81.0-1ubuntu1.15) です。
file はすでに最新バージョン (1:5.41-3ubuntu0.1) です。
file は手動でインストールしたと設定されました。
以下の追加パッケージがインストールされます:
  dpkg-dev fakeroot gir1.2-ayatanaappindicator3-0.1 gir1.2-ayatanaido3-0.4 icu-devtools libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libatk-bridge2.0-dev
  libatk1.0-dev libatspi2.0-dev libayatana-ido3-dev libayatana-indicator3-dev libblkid-dev libbrotli-dev libcairo2-dev libdatrie-dev libdbus-1-dev libdbus-glib-1-dev libdbus-glib-1-dev-bin
  libdbusmenu-glib-dev libdeflate-dev libegl-dev libegl1-mesa-dev libepoxy-dev libexpat1-dev libfakeroot libffi-dev libfontconfig-dev libfontconfig1-dev libfreetype-dev libfreetype6-dev
  libfribidi-dev libgdk-pixbuf-2.0-dev libgl-dev libgles-dev libgles1 libglib2.0-dev libglib2.0-dev-bin libglvnd-core-dev libglvnd-dev libglx-dev libgraphite2-dev libharfbuzz-dev
  libharfbuzz-gobject0 libice-dev libicu-dev libjavascriptcoregtk-4.0-dev libjbig-dev libjpeg-dev libjpeg-turbo8-dev libjpeg8-dev liblzma-dev libmount-dev libopengl-dev libpango1.0-dev
  libpcre16-3 libpcre2-16-0 libpcre2-dev libpcre2-posix3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libpixman-1-dev libpng-dev libpng-tools libpsl-dev libpthread-stubs0-dev libselinux1-dev
  libsepol-dev libsm-dev libsoup2.4-dev libthai-dev libtiff-dev libtiffxx5 libwayland-bin libwayland-dev libx11-dev libxau-dev libxcb-render0-dev libxcb-shm0-dev libxcb1-dev libxcomposite-dev
  libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxft-dev libxi-dev libxinerama-dev libxkbcommon-dev libxml2-dev libxrandr-dev libxrender-dev libxtst-dev
  lto-disabled-list make pango1.0-tools python3-distutils uuid-dev wayland-protocols x11proto-dev xorg-sgml-doctools xtrans-dev zlib1g-dev
提案パッケージ:
  debian-keyring libcairo2-doc libdatrie-doc freetype2-doc libgirepository1.0-dev libglib2.0-doc libxml2-utils libgraphite2-utils libgtk-3-doc libice-doc icu-doc liblzma-doc libpango1.0-doc
  librsvg2-doc libsm-doc libsoup2.4-doc libssl-doc libthai-doc libwayland-doc libx11-doc libxcb-doc libxext-doc make-doc graphicsmagick
以下のパッケージが新たにインストールされます:
  build-essential dpkg-dev fakeroot gir1.2-ayatanaappindicator3-0.1 gir1.2-ayatanaido3-0.4 icu-devtools libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl
  libatk-bridge2.0-dev libatk1.0-dev libatspi2.0-dev libayatana-appindicator3-dev libayatana-ido3-dev libayatana-indicator3-dev libblkid-dev libbrotli-dev libcairo2-dev libdatrie-dev
  libdbus-1-dev libdbus-glib-1-dev libdbus-glib-1-dev-bin libdbusmenu-glib-dev libdeflate-dev libegl-dev libegl1-mesa-dev libepoxy-dev libexpat1-dev libfakeroot libffi-dev libfontconfig-dev
  libfontconfig1-dev libfreetype-dev libfreetype6-dev libfribidi-dev libgdk-pixbuf-2.0-dev libgl-dev libgles-dev libgles1 libglib2.0-dev libglib2.0-dev-bin libglvnd-core-dev libglvnd-dev
  libglx-dev libgraphite2-dev libgtk-3-dev libharfbuzz-dev libharfbuzz-gobject0 libice-dev libicu-dev libjavascriptcoregtk-4.0-dev libjbig-dev libjpeg-dev libjpeg-turbo8-dev libjpeg8-dev
  liblzma-dev libmount-dev libopengl-dev libpango1.0-dev libpcre16-3 libpcre2-16-0 libpcre2-dev libpcre2-posix3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libpixman-1-dev libpng-dev libpng-tools
  libpsl-dev libpthread-stubs0-dev librsvg2-dev libselinux1-dev libsepol-dev libsm-dev libsoup2.4-dev libssl-dev libthai-dev libtiff-dev libtiffxx5 libwayland-bin libwayland-dev
  libwebkit2gtk-4.0-dev libx11-dev libxau-dev libxcb-render0-dev libxcb-shm0-dev libxcb1-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxft-dev
  libxi-dev libxinerama-dev libxkbcommon-dev libxml2-dev libxrandr-dev libxrender-dev libxtst-dev lto-disabled-list make pango1.0-tools python3-distutils uuid-dev wayland-protocols x11proto-dev
  xorg-sgml-doctools xtrans-dev zlib1g-dev
アップグレード: 0 個、新規インストール: 112 個、削除: 0 個、保留: 0 個。
30.3 MB のアーカイブを取得する必要があります。
この操作後に追加で 151 MB のディスク容量が消費されます。
続行しますか? [Y/n]
  • ローカル環境のインストール
bun install
bun install v1.0.29 (a146856d)

 + @tauri-apps/cli@1.5.11
 + @vitejs/plugin-vue@5.0.4
 + typescript@5.4.2
 + vite@5.1.5
 + vue-tsc@1.8.27 (v2.0.6 available)
 + @tauri-apps/api@1.5.3
 + vue@3.4.21

 50 packages installed [5.88s]
  • 起動
bun run tauri dev
hirukiyohirukiyo

Vuetify introduction

install

settings

  • create vuetify setting file
    mkdir src/plugins
    touch src/plugins/vuetify.ts
    
  • edit src/pluins/vuetify.ts
    // Vuetify
    import 'vuetify/styles'
    import { createVuetify } from 'vuetify'
    import * as components from 'vuetify/components'
    import * as directives from 'vuetify/directives'
    
    export default createVuetify({
      components,
      directives,
      theme: {
        defaultTheme: 'dark',
      }
    })
    
  • edit src/main.ts
    import { createApp } from "vue";
    import vuetify from './plugins/vuetify'
    import "./styles.css";
    import App from "./App.vue";
    
    createApp(App).use(vuetify).mount("#app");
    

using vuetify

  • create src/App2.vue
    <script setup lang="ts">
    import { ref } from 'vue'
    const title = ref('ページタイトル')
    </script>
    <template>
      <v-app class="compact">
        <v-main class="align-center">
          <v-container class="fill-height">
            <v-card class="mx-auto pa-12 pb-8" elevation="8" rounded="lg" width="448" min-width="448">
              <v-card-title class="pl-0 mb-3">{{ title }}</v-card-title>
            </v-card>
          </v-container>
        </v-main>
      </v-app>
    </template>
    
  • edit src/main.ts
    import { createApp } from "vue";
    import vuetify from './plugins/vuetify'
    // import "./styles.css";
    // import App from "./App.vue";
    import App2 from "./App2.vue";
    
    // createApp(App).use(vuetify).mount("#app");
    createApp(App2).use(vuetify).mount("#app");
    
  • result: Vuetifyコンポーネントが使える

Icon setting

  • https://vuetifyjs.com/en/features/icon-fonts/#material-design-icons
    bun add @mdi/font -D
    
  • log
    bun add @mdi/font -D
    bun add v1.0.29 (a146856d)
    
    installed @mdi/font@7.4.47
    
    1 package installed [1.94s]
    
  • edit src/plugins/vuetify.ts
    // Vuetify
    import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader
    import 'vuetify/styles'
    import { createVuetify } from 'vuetify'
    import * as components from 'vuetify/components'
    import * as directives from 'vuetify/directives'
    
    export default createVuetify({
      components,
      directives,
      theme: {
        defaultTheme: 'dark',
      },
      icons: {
        defaultSet: 'mdi', // This is already the default value - only for display purposes
      },
    })
    
  • edit src/App2.vue
    <script setup lang="ts">
    import { ref } from 'vue'
    const title = ref('ページタイトル')
    </script>
    <template>
      <v-app class="compact">
        <v-main class="align-center">
          <v-container class="fill-height">
            <v-card class="mx-auto pa-12 pb-8" elevation="8" rounded="lg" width="448" min-width="448">
              <v-card-title class="pl-0 mb-3">{{ title }}</v-card-title>
              <v-icon>mdi-square</v-icon>
              <v-icon>mdi-circle</v-icon>
              <v-icon>mdi-triangle</v-icon>
            </v-card>
          </v-container>
        </v-main>
      </v-app>
    </template>
    
  • result: mdi-iconが使える

SCSS

  • Install
    bun add -D sass
    
  • log
    bun add -D sass
    bun add v1.0.29 (a146856d)
    
    installed sass@1.71.1 with binaries:
      - sass
    
    16 packages installed [684.00ms]
    
  • create dir & files
    mkdir src/styles
    touch src/styles/variables.scss
    touch src/styles/main.scss
    
  • edit vsrc/styles/variables.scss
    $font-family: serif;
    
  • edit src/styles/main.scss
    @use 'variables' as var;
    @use 'vuetify' with (
      $body-font-family: var.$font-family,
      $font-size-root: 1rem,
      $line-height-root: 1.5,
      $border-radius-root: 4px
    );
    
  • edit src/plugins/vuetify.ts
    // Vuetify
    import '@mdi/font/css/materialdesignicons.css'
    // import 'vuetify/styles'  // -> src/styles/main.scss の @use 'vuetify'
    import '../styles/main.scss' // add import
    import { createVuetify } from 'vuetify'
    import * as components from 'vuetify/components'
    import * as directives from 'vuetify/directives'
    
    export default createVuetify({
      components,
      directives,
      theme: {
        defaultTheme: 'dark',
      },
      icons: {
        defaultSet: 'mdi',
      },
    })
    
  • result: 文字が羽つき(serif)になった
hirukiyohirukiyo

bun -> pnpm 移行

Macの場合、bun経由でtauriの実行ができない(2024-03-12時点)

bun run tauri dev
$ tauri dev

一旦、pnpmに移行する

  • node、pnpm インストール済み
node --version
v20.11.0
pnpm --version
8.15.4
  • pnpmで置き換える
rm -rf node_modules
rm bun.lockb
pnpm install
  • src-tauri/tauri.conf.jsonを編集
{
  "build": {
-    "beforeDevCommand": "bun run dev",
-    "beforeBuildCommand": "bun run build",
+    "beforeDevCommand": "pnpm run dev",
+    "beforeBuildCommand": "pnpm run build",
    "devPath": "http://localhost:1420",
    "distDir": "../dist"
  },
hirukiyohirukiyo

vue-router

  • パッケージ導入
pnpm add vue-router
  • src/router/index.ts ファイル作成
mkdir src/router
touch src/router/index.ts
  • src/router/index.ts 編集
import { createRouter, createWebHashHistory } from 'vue-router'
import Page1 from '../pages/Page1.vue'
import Page2 from '../pages/Page2.vue'

const router = createRouter({
  history: createWebHashHistory(),   // Hashでないと動作しない
  routes: [
    {
      path: '/',
      name: 'Page1',
      component: Page1
    },
    {
      path: '/page2',
      name: 'Page2',
      component: Page2
    },
  ]
})

export default router

  • src/main.ts 編集
import { createApp } from "vue";
import vuetify from './plugins/vuetify'
import App from "./App.vue";
import router from './router'

const app = createApp(App)

app.use(vuetify)
app.use(router)

app.mount("#app");
  • src/App.vue 編集
<template>
  <router-view></router-view>  
</template>
  • 以上で仕組みは完了
  • src/pages/Page1.vue、src/pages/Page2.vue 作成
mkdir src/pages
touch src/pages/Page1.vue
touch src/pages/Page2.vue
  • src/pages/Page1.vue を編集
<script setup lang="ts">
import { ref } from 'vue'
const title = ref('Page1')
</script>
<template>
  <v-app class="compact">
    <v-main class="align-center">
      <v-container class="fill-height">
        <v-card class="mx-auto pa-12 pb-8" elevation="8" rounded="lg" width="448" min-width="448">
          <v-card-title class="pl-0 mb-3">{{ title }}</v-card-title>
          <v-btn to="/page2">Page2</v-btn>
        </v-card>
      </v-container>
    </v-main>
  </v-app>
</template>
  • src/pages/Page2.vue を編集
<script setup lang="ts">
import { ref } from 'vue'
const title = ref('Page2')
</script>
<template>
  <v-app class="compact">
    <v-main class="align-center">
      <v-container class="fill-height">
        <v-card class="mx-auto pa-12 pb-8" elevation="8" rounded="lg" width="448" min-width="448">
          <v-card-title class="pl-0 mb-3">{{ title }}</v-card-title> 
          <v-btn to="/">Page1</v-btn>
        </v-card>
      </v-container>
    </v-main>
  </v-app>
</template>

  • 動作