【Tauri2】021——plugin(一)

目录

前言

正文

函数定义

看看plugins

看看register方法

使用plugin函数——Opener

注册

 看看tauri-plugin-opener的init方法

简单使用opener

通过记事本读取js文件

 导入OpenerExt

简单看open_path方法

结果

打开url

在文件夹中显示

看看函数签名

前端使用opener

打开文件

使用chrome打开url

看看请求


前言

这篇就来看看Builder中的方法plugin,主要是用于注册插件。

正文

函数定义

  #[must_use]
  pub fn plugin<P: Plugin<R> + 'static>(mut self, plugin: P) -> Self {
    self.plugins.register(Box::new(plugin));
    self
  }

需要一个参数plugin,泛型是P,泛型约束是trait Plugin

看看plugins

这是什么?

  /// All passed plugins
  plugins: PluginStore<R>,

这是一个结构体PluginStore

#[default_runtime(crate::Wry, wry)]
pub(crate) struct PluginStore<R: Runtime> {
  store: Vec<Box<dyn Plugin<R>>>,
}

只有一个store字段,是Vec,Vec中的元素类型是Box,Box的泛型约束是dyn Plugin<R>,动态分发的。

看看register方法

  pub fn register(&mut self, plugin: Box<dyn Plugin<R>>) -> bool {
    let len = self.store.len();
    self.store.retain(|p| p.name() != plugin.name());
    let result = len != self.store.len();
    self.store.push(plugin);
    result
  }

传入Box,需要满足对应的泛型约束。

先获取Vec的长度,

然后retain函数,过滤存储中的插件

1、保留那些名字不等于新插件名字的插件

2、移除所有同名的旧插件

接着比较过滤前后的长度:

1、如果长度不同,说明移除了旧插件,result 为 true

2、如果长度相同,说明没有旧插件被移除,result 为 false

将插件放到store中,返回result。

说白了,注册插件,就是把Plugin放到Box中,再把Box放到Vec中。

使用plugin函数——Opener

这个插件的作用

This plugin allows you to open files and URLs in a specified, or the default, application. It also supports “revealing” files in the system’s file explorer.

该插件可让您在指定或默认应用程序中打开文件和 URL。它还支持在系统文件资源管理器中 “显示 ”文件。

Tauri的插件还是比较多的。就简单使用Opener插件

Opener | Taurihttps://v2.tauri.app/plugin/opener/在Cargo.toml文件设置依赖

tauri-plugin-opener = "2"

注册

        .plugin(tauri_plugin_opener::init())

 看看tauri-plugin-opener的init方法

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::default().build()
}

返回TauriPlugin 结构体

可以发现TauriPlugin实现了trait Plugin

impl<R: Runtime, C: DeserializeOwned> Plugin<R> for TauriPlugin<R, C> 

 没有问题。

简单使用opener

通过记事本读取js文件

项目结构如下

在open.rs中,代码如下

use tauri_plugin_opener::OpenerExt;
use tauri::{command,AppHandle};
#[command]
pub fn open_by_notepad(app: AppHandle) {
    let path="./src/test.js";
    app.opener().open_path(path, Some("C:/Windows/System32/notepad.exe")).unwrap();
}

 导入OpenerExt

这个OpenerExt是个trait

pub trait OpenerExt<R: Runtime>

 为tauri::Manager实现了OpenerExt这个trait

impl<R: Runtime, T: Manager<R>> OpenerExt<R> for T 

导入了Manager,Apphandle就能使用Manager中的方法

因此Apphandle能使用OpenerExt中的方法。

如果不写这句话,报错如下

error[E0599]: no method named `opener` found for struct `AppHandle` in the current scope
   --> src\use_opener\open.rs:5:9
    |
5   |     app.opener().open_path(path, Some("C:/Windows/System32/notepad.exe")).unwrap();
    |         ^^^^^^ method not found in `AppHandle`
    |

 没有这个opener方法。

看看opener方法

    fn opener(&self) -> &Opener<R> {
        self.state::<Opener<R>>().inner()
    }

state中获取&Opener,看来Opener还是放在state中

既然如此,代码也可写成如下

#[command]
pub fn open_by_notepad(state: State<Opener<Wry>>) {
    let path="./src/test.js";
    let opener=state.inner();
    opener.open_path(path, Some("C:/Windows/System32/notepad.exe")).unwrap();
}

后面的open_path应该就是Opener中的方法。

简单看open_path方法

    #[cfg(desktop)]
    pub fn open_path(
        &self,
        path: impl Into<String>,
        with: Option<impl Into<String>>,
    ) -> Result<()>

简单地说

第一个参数&self,不必细说

第二个参数path,传一个能转化成String的的类型,比如说,"abcd"

第三个参数with,传一个Option,Option中泛型是能转化成String的的类型,比如说Some("abc")

返回Result

代码如上所示。

结果

笔者配置许可了默认许可

"opener:default",

注册通信函数并运行,结果如下 

 如果是使用默认,设参数with为None::<&str>,代码如下

#[command]
pub fn open_by_notepad(app: AppHandle) {
    let path="D:\\start\\src-tauri\\src\\test.js";
    app.opener().open_path(path, None::<&str>).unwrap();
}

 文件的路径要小心。

笔者使用默认的话,笔者是通过WebStorm打开的

打开url

直接给出代码

#[command]
pub fn open_by_url(app: AppHandle) {
    let url="https://www.baidu.com";
    app.opener().open_url(url,None::<&str>).unwrap();
}

使用默认程序,笔者使用的Edge,自动就打开,没有问题,可以传参,如果有,比如 "firefox"

需要可能配置权限,后面配置。

在文件夹中显示

#[command]
pub fn show(app: AppHandle) {
    app.opener().reveal_item_in_dir("./src/test.js").unwrap();
}

 结果成功。

看看函数签名

  pub fn reveal_item_in_dir<P: AsRef<Path>>(&self, p: P) 

 需要一个参数p,对应的泛型约束是AsRef<Path>,任何能转化成Path的类型。

  • String
  • &str
  • PathBuf
  • &Path
  • 其他实现了 AsRef<Path> 的自定义类型

前端使用opener

打开文件

关键代码如下

import { openPath } from '@tauri-apps/plugin-opener';    
async function handleClicked(){
        await openPath('D:/start/src-tauri/src/test.js');
}

需要配置许可

      {
      "identifier": "opener:allow-open-path",
      "allow": [
        {
          "path": "**"
        }
      ]
    }

匹配任意路径(包括所有文件和子目录)

运行成功。

使用chrome打开url

笔者默认使用Edge打开,使用chrome的话,需要配置许可

 {
      "identifier": "opener:allow-open-url",
      "allow": [
        {
          "url": "**",
          "app": "chrome"
        }
      ]
    }

前端代码如下

    async function handleClicked(){
        await openUrl("https://github.com","chrome");
    }

 如果Edge不是默认,想使用Edge,配置为

 {
      "identifier": "opener:allow-open-url",
      "allow": [
        {
          "url": "**",
          "app": "msedge"
        }
      ]
    }

也可以指定浏览器的路径,使用Edge Dev版本

 {
      "identifier": "opener:allow-open-url",
      "allow": [
        {
          "url": "**",
          "app":"C:\\Program Files (x86)\\Microsoft\\Edge Dev\\Application\\msedge.exe"
        }
      ]
    }
    async function handleClicked(){
        await openUrl(
            "https://github.com",
            "C:\\Program Files (x86)\\Microsoft\\Edge Dev\\Application\\msedge.exe");
    }

文件显示就不必细说。

看看请求

http://ipc.localhost/plugin%3Aopener%7Copen_path

{path: "D:/start/src-tauri/src/test.js"}

看来本质上是使用了invoke函数

实际上可以发现这样@tauri-apps_plugin-opener.js文件

内容如下

import {
  invoke
} from "/node_modules/.vite/deps/chunk-RGZSOVTY.js?v=5f8b5517";
import "/node_modules/.vite/deps/chunk-BUSYA2B4.js?v=5f8b5517";

// node_modules/.pnpm/@tauri-apps+plugin-opener@2.2.6/node_modules/@tauri-apps/plugin-opener/dist-js/index.js
async function openUrl(url, openWith) {
  await invoke("plugin:opener|open_url", {
    url,
    with: openWith
  });
}
async function openPath(path, openWith) {
  await invoke("plugin:opener|open_path", {
    path,
    with: openWith
  });
}
async function revealItemInDir(path) {
  return invoke("plugin:opener|reveal_item_in_dir", { path });
}
export {
  openPath,
  openUrl,
  revealItemInDir
};
//# sourceMappingURL=@tauri-apps_plugin-opener.js.map

看来就是使用了invoke。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值