当前位置: 首页 > news >正文

Dioxus后端代码

Dioxus 不只是个“前端框架”,它是个全栈框架——意思是:前端 + 后端,它都能写,还住一起,不拆家!

但默认情况下,它只当“前端小弟”。要想让它变成“全栈大佬”,得先在 Cargo.toml打开开关

修改依赖:开启“全栈模式”

[dependencies]
dioxus = { version = "0.6.0", features = ["fullstack"] }

再加一个“后门入口”:server 功能

[features]
default = []           # 关掉默认只跑前端
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
mobile = ["dioxus/mobile"]
server = ["dioxus/server"]  # 加上这句:后端也能跑!

如果你创建项目时选了“yes,我要全栈”,那这步已经自动完成了!

注意:改完这些,重启服务!
因为 dx serve 不会自动热重载这个配置。

运行时要加平台参数:

dx serve --platform web

等它重新编译完,你会看到控制台显示:

16:35:41 [dev] Build completed successfully in 167722ms, launching app! 💫
╭────────────────────────────────────────────────────────────────────────────────────────── /:more ╮
│  App:     ━━━━━━━━━━━━━━━━━━━━━━━━━━  🎉 178.0s    Platform: Web + fullstack                     │
│  Server:  ━━━━━━━━━━━━━━━━━━━━━━━━━━  🎉 178.0s    App features: ["web"]                         │
│  Status:  Serving hot_dog 🚀 186.1s                Serving at: http://127.0.0.1:8080             │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯

第二步:用“服务器函数”——前后端的“心灵感应”

Dioxus 提供了一个超爽的功能:服务器函数(Server Functions)
你可以把它理解为:

写一个函数,前后端自动打通,像魔法一样!

你写一个函数,标个 #[server]
它就能在前端调用,在后端执行,中间的网络通信、数据打包,全给你包了!

举个栗子:收藏一只狗

#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {Ok(())
}

就这么简单!你写的是一个普通函数,但 Dioxus 暗地里做了三件事:

  1. 在前端:变成一个 reqwest 请求,发给后端
  2. 在后端:变成一个 axum 接口,接收请求
  3. 自动注册:启动时自动挂载到路由上,比如 /api/save_dog

你可以把它想象成“远程遥控器”:
前端按按钮,后端执行任务,中间不用你接电线。


前后端是怎么“分家过日子”的?

虽然住一起,但前后端还是两个独立程序

  • 前端:跑在浏览器里,用 --feature web 编译
  • 后端:跑在服务器上,用 --feature server 编译

这就意味着:

不能把后端的秘密暴露给前端!

比如,你不能这样写:

//  危险!密码会被打包进前端代码!
static DB_PASSWORD: &str = "123456";#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {connect_to_db(DB_PASSWORD); // 前端也能看到这个密码!Ok(())
}

正确做法:把敏感代码放进 #[cfg(feature = "server")] 里:

#[cfg(feature = "server")]
mod server_utils {pub static DB_PASSWORD: &str = "123456";
}#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {let password = server_utils::DB_PASSWORD;connect_to_db(password);Ok(())
}

这样,server_utils 只在后端编译,前端完全看不到!

第三步:管理依赖——谁该上车,谁该下车?

有些库只能在服务器上跑,比如 tokiostd::fs
有些只能在浏览器跑,比如 web-sys

为了避免“张飞穿针”——(服务器代码跑到浏览器里去执行)
我们要用 optional = true 控制依赖:

[dependencies]
tokio = { version = "1", optional = true }[features]
server = ["dioxus/server","dep:tokio"]  # 只有开启 server 功能时,才引入 tokio

这样,前端打包时,tokio 根本不会被打进去!

给“潮狗”加个“收藏本”!

现在,我们来实现真正的“收藏”功能:把用户喜欢的狗图链接,存到一个叫 dogs.txt 的文件里。

生产环境当然要用数据库,但咱们先用文件练手!

#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {use std::io::Write;// 打开 dogs.txt,没有就创建,有就追加let mut file = std::fs::OpenOptions::new().write(true).append(true).create(true).open("dogs.txt").unwrap();// 把狗图链接写进去,加个换行writeln!(file, "{}", image).unwrap();Ok(())
}

前端调用:一键收藏!

回到前端,我们改一下“收藏”按钮:

button {id: "save",onclick: move |_| async move {let current = img_src.cloned().unwrap(); // 拿到当前狗图img_src.restart();                       // 换下一只let _ = save_dog(current).await;         // 调用服务器函数!},"收藏!"
}

效果:

  1. 点“收藏”
  2. 当前狗图链接传给后端
  3. 后端写入 dogs.txt
  4. 页面自动换狗

从此,你的“心动小狗”都有地方安家了!

完整代码

use dioxus::prelude::*;static CSS: Asset = asset!("/assets/main.css");fn main() {dioxus::launch(App);
}#[derive(Clone)]
struct TitleState(String);#[component]
fn App() -> Element {use_context_provider(|| TitleState("HotDog".to_string()));rsx! {document::Stylesheet {href:CSS}Title {  }DogView {  }}
}#[component]
fn Title() -> Element {let title = use_context::<TitleState>();rsx! {div { id: "title",h1 { "{title.0}" }}}
}#[derive(serde::Deserialize)]
struct DogApi {message: String,
}#[component]
fn DogView() -> Element {// 用use_resource 创建一个“资源”,他会自动跑这个异步任务let mut img_src = use_resource(|| async move {reqwest::get("https://dog.ceo/api/breeds/image/random").await.unwrap().json::<DogApi>().await.unwrap().message});rsx! {div { id: "dogview",img { src: img_src.cloned().unwrap_or_default() }}div { id: "buttons",button { onclick: move  |_| img_src.restart(), id: "skip", "skip!" }button { onclick: move  |_| async move{let current = img_src.cloned().unwrap();img_src.restart();_= save_dog(current).await;}, id: "save", "save!" }}}
}#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {use std::io::Write; //这一行很重要let mut file = std::fs::OpenOptions::new().write(true).append(true).create(true).open("dogs.txt").unwrap();writeln!(file, "{}", image).unwrap();Ok(())
}

全栈开发的“三板斧”

武器作用类比
fullstack feature打开全栈模式给房子通水电
#[server] 函数前后端通信心灵感应遥控器
cfg(feature = "server")隔离后端代码保险柜,只给后端看

从记事本升级到数据库!

今天,我们要给它升级——装一个真正的“狗窝”:数据库

ID狗图链接(url)
1https://dog1.jpg
2https://dog2.png
3https://dog3.gif

它不仅能存数据,还能:

  • 快速查找
  • 防止重复
  • 自动编号
  • 不怕断电
  • 多人同时用也不打架

比记事本强一万倍!


选个啥数据库?——先看你是“独居”还是“合租”

市面上数据库五花八门,挑花眼?
别急,我们按场景分类:

1. 独居党(单用户) → 用 SQLite
  • 就一个文件,像U盘一样塞进App
  • 不用装服务,不用配服务器
  • 轻量、可靠、零配置
  • 适合你自己的小项目

HotDog 就是“独居狗”,所以选 SQLite!

2. 合租党(多用户) → 用 PostgreSQL / MySQL
  • 支持多人同时访问
  • 功能强大,插件多
  • 适合正式上线的App
其他“特种兵”数据库:
  • Redis:超快“记忆闪存”,适合存临时数据(比如验证码)
  • MongoDB:不规则数据的家,比如用户自定义表单
  • SurrealDB:新晋“六边形战士”,啥都能干
  • CockroachDB:分布式“永不断电”数据库

一句话总结:
大部分项目,PostgreSQL 或 MySQL 准没错。
小项目、个人玩具?SQLite 是你的最佳拍档!

给 HotDog 装上 SQLite 引擎!

现在,我们动手给“潮狗”换心脏!

第一步:加依赖 —— 把“数据库司机”请上车

我们要用 rusqlite 这个 crate,它是 Rust 里操作 SQLite 的“老司机”。

但注意:数据库操作只能在后端运行!
所以我们要把它“锁”在 server 功能里。

[dependencies]
rusqlite = { version = "0.32.1", optional = true }[features]
server = ["dioxus/server", "dep:rusqlite"]

dep:rusqlite 意思是:只有开启 server 时,才装这个库。
前端打包时,它不会出现,避免“车开到浏览器里去”。


第二步:创建数据库 —— 打好地基

我们用 thread_local! 来管理数据库连接(技术细节先不管,你就当它是“安全保险箱”)。

#[cfg(feature = "server")]
thread_local! {pub static DB: rusqlite::Connection = {// 打开或创建 "hotdog.db" 文件let conn = rusqlite::Connection::open("hotdog.db").unwrap();// 创建一张叫 "dogs" 的表conn.execute_batch(r#"CREATE TABLE IF NOT EXISTS dogs (id INTEGER PRIMARY KEY,url TEXT NOT NULL);"#).unwrap();conn};
}

效果:运行后,你会看到项目里多了一个 hotdog.db 文件!它就是你的“数字狗窝”!


第三步:把狗图存进去 —— 从“写记事本”升级到“建档案”

原来的 save_dog 是往文本文件里写一行,
现在我们用 SQL 语句,把数据“规规矩矩”存进数据库:

#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {DB.with(|db| {db.execute("INSERT INTO dogs (url) VALUES (?1)", &[&image])})?;Ok(())
}

解释:

  • INSERT INTO dogs:往 dogs 表插入数据
  • VALUES (?1):第一个参数是 image
  • ?1 是防SQL注入的安全写法

点一次“收藏”,就往表里加一条记录,整齐、安全、不重复!


测试一下:看看你的“狗窝”长啥样?

  1. 启动 App,点几下“收藏”
  2. 打开项目文件夹,找到 hotdog.db
  3. 用一个 SQLite 查看工具(比如 DB Browser for SQLite)打开它
  4. 查看 dogs

在这里插入图片描述

你应该能看到你收藏的所有狗图链接!
恭喜,你的 App 现在是个正经的“全栈应用”了!

Rust 里的数据库工具箱(推荐版)

Rust 的数据库生态正在飞速发展,这里是你该认识的“工具们”:

工具特点适合谁
rusqlite简单直接,无魔法,SQLite 专用小项目、初学者
Sqlx支持 PostgreSQL/MySQL/SQLite,异步友好中大型项目
SeaORM基于 Sqlx 的 ORM,像写 Rust 一样写数据库喜欢“面向对象”风格的人
Turbosql超简洁,自动推导,SQLite 专用追求极简的人
rust-postgresPostgreSQL 专用,API 类似 rusqlite只用 PG 的人

数据库放哪?——自己养 or 托管?

你可以:

  • 自己养:在自己电脑或服务器上跑数据库(免费,但要操心)
  • 托管服务:花钱让别人帮你管(省心,但要付钱)
  • 数据库三步走
步骤做什么类比
1. 选数据库单用户用 SQLite,多用户用 PostgreSQL住公寓还是住别墅?
2. 加依赖rusqlite + feature = "server"请个靠谱的装修队
3. 写代码创建表 → 插入数据 → 查看结果把狗从纸条搬到狗窝
http://www.dtcms.com/a/391024.html

相关文章:

  • 概念篇:ReactJS + AppSync + DynamoDB 性能优化核心概念
  • 实践篇:ReactJS + AppSync + DynamoDB 性能优化实践
  • GPS 定位:守护财产安全的 “隐形防盗锁”
  • Vue3 + Three.js 进阶实战:批量 3D 模型高效可视化、性能优化与兼容性解决方案
  • 海外VPS索引版本兼容性检查,版本兼容问题检测与多系统适配方法
  • uniapp 常用
  • C语言入门教程 | 阶段一:基础语法讲解(数据类型与运算符)
  • 现代AI工具深度解析:从GPT到多模态的技术革命与实战应用
  • 自由学习记录(101)
  • 2025最新口红机防篡改版本源码
  • Unity2D-图片导入设置
  • 今日赛事前瞻:德甲:斯图加特VS圣保利,意甲:莱切VS卡利亚里
  • AWS CloudTrail 监控特定 SQS 队列事件完整配置指南
  • 【算法】【优选算法】BFS 解决 FloodFill 算法
  • 量化交易 - Stochastic Gradient Descent Regression (SGDRegressor) 随机梯度下降回归 - 机器学习
  • AWS WAF防护IoT设备劫持攻击:智能设备安全防护实践
  • 分享mysql数据库自动备份脚本(本机和docker都可用)
  • avue crud表头跨列
  • 鸿蒙网络优化实战:从智能切换到缓存加速的完整指南
  • Redis-实现分布式锁
  • 软件工程实践五:Spring Boot 接口拦截与 API 监控、流量控制
  • 【LINUX网络】NAT _ 代理_ 内网穿透
  • 智慧养老+数字大健康:当科技为“银发时代”按下温暖加速键
  • rook-ceph的ssd类osd的纠删码rgw存储池在迁移时的异常处理
  • Http升级Https使用Certbot申请证书并免费续期
  • scTenifoldKnk:“虚拟敲除基因”,查看转录组其他基因的变化幅度(升高or降低)
  • 牛客算法基础noob47 校门外的树
  • AD-GS:稀疏视角 3D Gaussian Splatting 的“交替致密化”,同时抑制浮游物与保留细节
  • maven package多出来一个xxx.jar.original和一个xxx-shaded.jar是什么?怎么去掉
  • Gin 框架中使用 Validator 进行参数校验的完整指南