Tauri教程-实战篇-第六节 托盘、请求完善
“如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》
“有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》
“维持现状意味着空耗你的努力和生命。”——纪伯伦
第六节 托盘、请求完善
一. 简介
在上面的章节我们完成了 窗口和请求 功能的实现,本章节我们将对系统现有的代码进行修改,以实现完整的功能。
二. 托盘完善
打开项目中 “tary.rs”文件,我们在之前介绍了如何创建和定义托盘菜单,但在实现部分并没有实现它,下面我们来看看它的具体功能和如何实现它。
1. 点击事件
点击托盘图标时,我们希望展示应用界面到桌面最前面,它的逻辑在:on_tray_icon_event 实现处理,它接收2各参数,
-
TrayIcon
id: TrayIconId, inner: tray_icon::TrayIcon, app_handle: AppHandle<R>,
-
TrayIconEvent
实现思路:点击托盘图标,获取Tauri的主窗口,并显示它。
实现代码如下:
let main_win=tray.app_handle().get_webview_window("main").unwrap();
main_win.show().unwrap();
main_win.unminimize().unwrap();
main_win.set_focus().unwrap();
2. 显示事件
显示事件和点击事件的实现思路一致, 这里提供另外一种代码:
....
"show" => {
for (key, value) in app.webview_windows() {
if key == "main" {
value.show().unwrap();
}
}
}
....
3. 退出事件
"quit" => {
app.exit(0);
}
调用app.exit api 就可以
4. 完整代码如下:
use tauri::{
menu::{Menu, MenuItem, Submenu},
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
Manager, Runtime,
};
pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
let quit_i = MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?;
let set_i = MenuItem::with_id(app, "set", "设置", true, None::<&str>)?;
let show_i = MenuItem::with_id(app, "show", "显示窗口", true, None::<&str>)?;
// 分割线
let menu = Menu::with_items(app, &[&show_i, &set_i, &quit_i])?;
let _ = TrayIconBuilder::with_id("tray")
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu)
.on_menu_event(move |app, event| match event.id.as_ref() {
"show" => {
for (key, value) in app.webview_windows() {
if key == "main" {
value.show().unwrap();
}
}
}
"set" => {
println!("set");
}
"quit" => {
app.exit(0);
}
// Add more events here
_ => {}
})
.on_tray_icon_event(|tray, event: TrayIconEvent| {
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
let main_win=tray.app_handle().get_webview_window("main").unwrap();
main_win.show().unwrap();
main_win.unminimize().unwrap();
main_win.set_focus().unwrap();
}
})
.build(app);
Ok(())
}
三 . 页面HTTP接口改造
1. 修改 Api hook 增加请求前缀
const res = await fetch(“http://localhost:8080” + url, options);
“http://localhost:8080” 为你的实际服务地址
这里要注意先修改权限配置如下:
{
"identifier": "http:default",
"allow": [
{
"url": "http://**"
},
{
"url": "https://**"
},
{
"url": "http://*:*"
},
{
"url": "https://*:*"
}
],
"deny": [
{
"url": "https://private.tauri.app"
}
]
},
2. 页面代码完善后如下
<template>
<el-container>
<el-header>
<el-col :span="8">
<el-input v-model="queryInput" placeholder="请输入姓名搜索" />
</el-col>
<div>
<el-button type="primary" @click="handleAdd">增加</el-button>
<el-button
type="danger"
@click="handleListDel"
v-if="multipleSelection.length > 0"
>删除</el-button
>
</div>
</el-header>
<el-main>
<el-table
:data="tableData"
style="width: 100%; height: 100%"
border
ali
@selection-change="handleSelectionChange"
ref="multipleTableRef"
>
<el-table-column align="center" type="index" label="Xh" width="55" />
<el-table-column
align="center"
prop="type"
label="紧急情况"
:formatter="
(row, column, cellValue, index) => {
if (cellValue === 1) {
return '急';
} else if (cellValue === 2) {
return '紧急';
}
return '一般';
}
"
width="90"
/>
<el-table-column
align="left"
header-align="center"
prop="title"
label="标题"
width="200"
/>
<el-table-column
align="center"
prop="name"
label="联系人"
width="100"
/>
<el-table-column
align="center"
prop="time"
label="截止时间"
width="180"
/>
<el-table-column
align="center"
prop="state"
:formatter="
(row, column, cellValue, index) => {
if (cellValue === 1) {
return '未完成';
}
return '已完成';
}
"
label="状态"
width="120"
/>
<el-table-column align="center" fixed="right" label="操作" width="120">
<template #default="scope">
<!-- <el-button
link
type="danger"
size="small"
@click="handleRowDel(scope.row.id)"
>删除</el-button
> -->
<el-button
link
type="primary"
size="small"
@click="handleEdit(scope.row)"
>编辑</el-button
>
</template>
</el-table-column>
</el-table>
<!--dialog 弹窗-->
<el-dialog
v-model="dialogFormVisible"
:title="dialogType === 'add' ? '新增' : '编辑'"
>
<el-form :model="tableForm" label-width="auto">
<el-form-item label="紧急情况">
<el-select
v-model="tableForm.type"
:disabled="dialogType !== 'add'"
placeholder="紧急情况"
>
<el-option label="一般" :value="0" />
<el-option label="急" :value="1" />
<el-option label="紧急" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="标题">
<el-input
v-model="tableForm.title"
:disabled="dialogType !== 'add'"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="联系人">
<el-input
v-model="tableForm.name"
:disabled="dialogType !== 'add'"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="截止时间">
<el-date-picker
v-model="tableForm.time"
:disabled="dialogType !== 'add'"
type="datetime"
placeholder="截止时间"
/>
</el-form-item>
<el-form-item label="状态">
<el-select
v-model="tableForm.state"
autocomplete="off"
placeholder="状态"
>
<el-option label="未完成" :value="0" />
<el-option label="已完成" :value="1" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="dialogConfirm">确认</el-button>
</span>
</template>
</el-dialog>
</el-main>
</el-container>
</template>
<script setup>
import { ref, watch, onMounted, computed } from "vue";
import useApi from "../../tauri/hooks/api";
import {
isPermissionGranted,
requestPermission,
sendNotification,
} from "@tauri-apps/plugin-notification";
const api = useApi();
//数据
const queryInput = ref("");
const tableData = ref([]);
let tableDataCopy = computed(() => tableData.value);
const multipleSelection = ref([]); //多选
const dialogFormVisible = ref(false); //是否打开
const formLabelWidth = "80px"; //弹出框 标题长度
const tableForm = ref({});
const dialogType = ref("add");
//监控数据
watch(queryInput, (val) => {
if (val.length > 0) {
tableData.value = tableData.value.filter((item) =>
item.title.toLowerCase().match(val.toLowerCase())
);
} else {
loadPageData();
}
});
//选择事件
const handleSelectionChange = (val) => {
multipleSelection.value = [];
val.forEach((item) => {
multipleSelection.value.push(item.id);
});
};
//添加按钮
const handleAdd = (val) => {
tableForm.value = {};
dialogType.value = "add";
dialogFormVisible.value = true;
};
//编辑按钮
const handleEdit = (val) => {
tableForm.value = val;
dialogType.value = "edit";
dialogFormVisible.value = true;
};
//删除一条按钮
const handleRowDel = (id) => {
console.log(id);
let index = tableData.value.findIndex((item) => item.id === id);
tableData.value.splice(index, 1);
};
//删除多条
const handleListDel = () => {
multipleSelection.value.forEach((id) => {
handleRowDel(id);
});
multipleSelection.value = [];
};
//确认按钮
const dialogConfirm = () => {
if (dialogType.value === "add") {
api.send("/task/addTask", "POST", tableForm.value).then((res) => {
if (res) {
loadPageData();
}
});
// tableData.value.push({
// id: tableData.value.length + 1,
// ...tableForm.value,
// });
} else {
api.send("/task/updateTask", "PATCH", tableForm.value).then((res) => {
if (res) {
loadPageData();
}
});
// let index = tableData.value.findIndex((item) => item.id === tableForm.id);
// tableData[index] = tableForm;
}
dialogFormVisible.value = false;
};
const loadPageData = (not = false) => {
api.send("/task/queryTask", "GET").then(async (res) => {
tableData.value = res;
});
};
onMounted(() => {
loadPageData(true);
});
</script>
<style lang="scss" scoped>
.el-container {
width: 100%;
height: 100%;
padding: 10px;
background-color: #f0f2f5;
.el-header {
background-color: #b3c0d1;
color: #333;
line-height: 60px;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.el-main {
background-color: #b3c0d1;
color: #333;
text-align: center;
padding: 10px;
}
}
</style>
四 代码仓库
项目仓库:https://gitee.com/Elcker/tv_task.git