iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
Modern Web

30天學習Tauri系列 第 3

3.Hello, Tauri

  • 分享至 

  • xImage
  •  

昨日簡單創建完專案後,我們今天簡單的看一下專案架構

Tauri專案架構

我們能看到Tauri專案主要分為src和src-tauri
folder directory:
https://ithelp.ithome.com.tw/upload/images/20220918/201089312QxEL4uCdZ.png

1.src directory:
https://ithelp.ithome.com.tw/upload/images/20220918/201089319F1EKsgVVj.png

用於開發並且顯示畫面,主要是跟使用者互動,並將操作結果以籍資料傳輸到tauri內部去做處理

2.src-tauri directory:
https://ithelp.ithome.com.tw/upload/images/20220918/20108931eJgmvRwwTl.png

主要是app內部功能,類似於後端,進行一些邏輯以及資料的處理,並且能與系統平台相互動

tauri.conf.json
主要是用來設定app的一些功能,像是window大小,以及是否能resize,或者是build的設定

簡易理解Tauri運作

我們試著觀察todo\src\pages裡的index.tsx

import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
import Image from "next/image";
import reactLogo from "../assets/react.svg";
import tauriLogo from "../assets/tauri.svg";
import nextLogo from "../assets/next.svg";

function App() {
  const [greetMsg, setGreetMsg] = useState("");
  const [name, setName] = useState("");

  async function greet() {
    // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
    setGreetMsg(await invoke("greet", { name }));
  }

  return (
    <div className="container">
      <h1>Welcome to Tauri!</h1>

      <div className="row">
        <span className="logos">
          <a href="https://nextjs.org" target="_blank">
            <Image
              width={144}
              height={144}
              src={nextLogo}
              className="logo next"
              alt="Next logo"
            />
          </a>
        </span>
        <span className="logos">
          <a href="https://tauri.app" target="_blank">
            <Image
              width={144}
              height={144}
              src={tauriLogo}
              className="logo tauri"
              alt="Tauri logo"
            />
          </a>
        </span>
        <span className="logos">
          <a href="https://reactjs.org" target="_blank">
            <Image
              width={144}
              height={144}
              src={reactLogo}
              className="logo react"
              alt="React logo"
            />
          </a>
        </span>
      </div>

      <p>Click on the Tauri, Next, and React logos to learn more.</p>

      <div className="row">
        <div>
          <input
            id="greet-input"
            onChange={(e) => setName(e.currentTarget.value)}
            placeholder="Enter a name..."
          />
          <button type="button" onClick={() => greet()}>
            Greet
          </button>
        </div>
      </div>

      <p>{greetMsg}</p>
    </div>
  );
}

export default App;

我們看到了一個greet():

  async function greet() {
    // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
    setGreetMsg(await invoke("greet", { name }));
  }

我們能看到他呼叫了invoke這個method,而這個invoke(),試著與tauri內部進行溝通的函式,然後我們看到他呼叫了內部greet這個方法

setGreetMsg(await invoke("greet", { name }));

接著,我們打開todo\src-tauri\src\main.rs

#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

能看到greet這個方法,輸入name後會傳回一個字串

#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

https://ithelp.ithome.com.tw/upload/images/20220918/20108931QlsDqyoAZ7.png

接下來我們測試一下,嘗試修改todo\src\pages\index.tsx為:

import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";

function App() {
  return (
    <div className="container">
      <h1>Welcome to Todo List</h1>
    </div>
  );
}

export default App;

https://ithelp.ithome.com.tw/upload/images/20220918/20108931f7P3MrB2sm.png

接下來,我們簡單實作Todo List

import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";

const itemStyle = {
  padding: '8px',
};

function App() {
  
  const [todos, setTodos] = useState<string[]>([]);
  const [todo, setTodo] = useState("");

  const handleTaskAdd = async () => {
    setTodos([todo, ...todos]);
    setTodo('');
  }

  const handleTaskDelete = async (index) => {
    setTodos(todos.filter(e => e !== todos[index]));
    setTodo('');
  }


  return (
    <div className="container">
      <h1>Welcome to Todo List</h1>
      
      <div className="row">
        <input
          id="greet-input"
          onChange={(e) => setTodo(e.currentTarget.value)}
          placeholder="Enter a task..."
          value={todo}
        />
        <button type="button" onClick={() => handleTaskAdd()}>
          Add
        </button>
        
      </div>
      <hr />
      {todos.map((todo, index) => {
        return (
          <div className="row" key={index}>
            <div style={itemStyle}>{todo}</div>
            <button type="button" onClick={() => handleTaskDelete(index)}>
              Delete
            </button>
          </div>
        );
      })}
    </div>
  );
}

export default App;

https://ithelp.ithome.com.tw/upload/images/20220918/201089314QPTaIcvpV.png

https://ithelp.ithome.com.tw/upload/images/20220918/20108931oNgikzzMOD.png


今天我們再畫面上成功創建一個簡單的todo,接下來的任務就是將資料傳遞至tauri內部。在明天開始撰寫前,我們先簡單的講解下rust


上一篇
2.準備與安裝環境
下一篇
4.Rust-lang (一)
系列文
30天學習Tauri30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言