BST Tauri 开发笔记(6)- 为Tauri接口注入全局变量

目的,想要在对JS能调用的invoke接口中提供持续的db connection对象,一开始想用比较简单粗暴的方式每次都重新连接一次本地的sqlite数据库,后来发现Tauri可以注入的功能,就有了以下的使用方法:

main.rs

use rusqlite::Connection;
use tauri::State;
use std::sync::Mutex;

struct DbConnection {
    db: Mutex<Option<Connection>>,
}

// 注入的state会自动匹配声明的变量
#[tauri::command]
fn query(some_param: i32, connection: State<DbConnection>) -> Vec<String> {
    println!("some_param={}", some_param);

    let db = connection.db.lock();
    let conn = db.as_ref().unwrap().as_ref().unwrap();
    let mut stmt = conn.prepare("SELECT name_en FROM books").unwrap();
    let rows = stmt.query_map([], |row| row.get(0)).unwrap();

    let mut names = Vec::new();
    for name_result in rows {
        names.push(name_result.unwrap());
    }
    names
}

fn main() {
    tauri::Builder::default()
        // 注入state
        .manage(DbConnection {
            db: Mutex::new(Some(
                Connection::open("./resources/db.sqlite").unwrap(),
            )),
        })
        .invoke_handler(tauri::generate_handler![query])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

在React中使用接口:

App.tsx

import { invoke } from '@tauri-apps/api'
import { FunctionComponent } from 'react'

interface AppProps {}

const App: FunctionComponent<AppProps> = () => {
  return (
    <div className="tw-w-screen tw-h-screen">
      <button
        onClick={async () => {
          const names = await invoke('query', { someParam: 123 })
          console.log(names)
        }}
      >
        query3
      </button>
    </div>
  )
}

export default App

这样就能在所有的tauri接口中使用同一个db 的connection对象了!

文档:https://docs.rs/tauri/1.2.4/tauri/trait.Manager.html#method.manage

发表回复