我们如何使用Tauri使Rust结构体示例方法可用于Vue前端?

kcwpcxri  于 2023-03-24  发布在  Vue.js
关注(0)|答案(1)|浏览(349)

简而言之,使用Rust后端和Vue前端的Tauri应用程序。#[tauri::command] 很好,并且都是纯函数,但是如果我们需要在后端保留某种状态,比如说结构体示例,会发生什么?这是我的例子:
金牛座进入点:main.rs

mod random_number_generator;
use random_number_generator::RandomNumberGenerator;

fn main() {
    // instance to manage the vector state
    let ng = RandomNumberGenerator::new();

    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![generate]) <-- how to access the "generate" of ng?
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

一个简单的struct及其实现:随机数生成器. rs

use rand::Rng;

pub struct RandomNumberGenerator
{
    used_numbers_repository: Vec<i64>,
}

impl RandomNumberGenerator {
    pub fn new() -> Self {
        RandomNumberGenerator {
            used_numbers_repository: Vec::new()
        }
    }

    #[tauri::command]  <-- this is not allowed
    pub fn generate(self, minimum: i64, maximum: i64) -> String {
        if minimum < 0 {
            return format!("Random number between {} and {}: minimum must be positive.", minimum, maximum);
        }

        if minimum >= maximum {
            return format!("Random number between {} and {}: maximum must be more than minimum.", minimum, maximum);
        }

        let mut rng = rand::thread_rng();
        let mut number: i64 = rng.gen_range(minimum..maximum + 1);

        while self.used_numbers_repository.contains(&number) {
            number = rng.gen_range(minimum..maximum + 1);
        }

        self.store_number(number);
        format!("A random number between {} and {}? Here you go: {}.", minimum, maximum, number)
    }

    #[tauri::command]  <-- this is not allowed
    pub fn used_numbers(&self) -> Vec<i64> {
        self.used_numbers_repository
    }

    fn store_number(&mut self, number: i64) {
        self.used_numbers_repository.push(number);
    }
}

一个简单的vue组件:RandomGenerator.vue

<script setup lang="ts">
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/tauri";

const generatedMessage = ref("");
const minimum = ref(0);
const maximum = ref(999);

async function generate() {
    generatedMessage.value = await invoke("generate", { minimum: minimum.value, maximum: maximum.value })
}
</script>

<template>
  <div class="card">
    <input type="number" v-model="minimum" placeholder="minimum" />
    <input type="number" v-model="maximum" placeholder="maximum" />
    <button type="button" @click="generate()">Generate</button>
  </div>

  <p>{{ generatedMessage }}</p>
</template>

[tauri::command]不允许结构化方法。

如果不使用其他软件包,例如状态管理,这可能吗?

pgpifvop

pgpifvop1#

#[tauri::command]很好,而且都是纯函数,但是如果我们需要在后端保留某种状态,比如说结构体示例,会发生什么呢?
在Tauri中,你不需要使用方法,而是使用Tauri应用程序通过Manager::manage方法处理的State(类似于Rust web框架中的端点,如Actix,Axum或Rocket的工作方式)。在指南的这一部分中阅读更多关于tauri中状态管理的信息。
也就是说,这可能是一个适用于Tauri的设置,使用你的RandomNumberGenerator作为状态,同时将你的generate命令暴露给Vue.js:

use tauri::State;

pub struct RandomNumberGenerator
{
    used_numbers_repository: Vec<i64>,
}

#[tauri::command]
pub fn generate(rng: State<RandomNumberGenerator>, minimum: i64, maximum: i64) -> String {
    todo!();
}

fn main() {
    let ng = RandomNumberGenerator::new();

    tauri::Builder::default()
        .manage(ng) // manage ng as app state
        .invoke_handler(tauri::generate_handler![generate])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

在Vue中,你可以像在你的例子中那样调用这个命令:

await invoke("generate", { minimum: minimum.value, maximum: maximum.value })

相关问题