
첫 번째 Dioxus 애플리케이션에 오신 것을 환영합니다! 이 가이드는 Dioxus 앱을 처음 만드는 과정을 안내하고, 핵심 개념을 이해하며, Rust를 사용하여 인터랙티브 사용자 인터페이스를 구축하는 데 필요한 일반적인 패턴을 살펴봅니다.
모든 Dioxus 여정은 간단한 "Hello, World!" 애플리케이션으로 시작됩니다. 이 간단한 예시는 Dioxus 앱의 기본 구조를 보여줍니다.
use dioxus::prelude::*;
fn main() {
dioxus::launch(app);
}
fn app() -> Element {
rsx! {
div { "Hello, world!" }
}
}
Prelude Import : 이 라인은 함수, 유형, RSX 매크로를 use dioxus::prelude::*;포함하여 필요한 모든 필수 항목을 가져옵니다 .launchElement
진입점 : 지정된 루트 구성 요소로 애플리케이션을 시작하는 main()함수 호출입니다 .dioxus::launch(app)
루트 구성 요소 : 이 app()함수는 Dioxus UI의 구성 요소인 ->를 반환합니다 Element. UI 로직이 여기에 위치합니다.
RSX 매크로 : 이 rsx!매크로를 사용하면 Rust 내에서 HTML과 유사한 구문을 작성하여 UI 구조를 선언적으로 만들 수 있습니다.
Dioxus는 가상 DOM 시스템을 갖춘 컴포넌트 기반 아키텍처를 따릅니다. 각 아키텍처의 구성 요소는 다음과 같습니다.
이 launch()기능은 활성화된 기능에 따라 대상 플랫폼을 자동으로 감지하고 적절한 렌더러 소스를 구성합니다 .
Hello World 예제에 상호작용 기능을 추가하여 만들어 보겠습니다. 간단한 카운터 애플리케이션은 다음과 같습니다.
use dioxus::prelude::*;
fn main() {
dioxus::launch(app);
}
fn app() -> Element {
let mut count = use_signal(|| 0);
rsx! {
div {
h2 { "Count: {count}" }
button { onclick: move |_| count += 1, "Increment" }
button { onclick: move |_| count -= 1, "Decrement" }
}
}
}
주요 개념 :
더 복잡한 애플리케이션에서는 데이터 목록을 다루는 경우가 많습니다. 이 카운터 예제는 여러 항목을 관리하는 방법을 보여줍니다.
use dioxus::prelude::*;
fn main() {
dioxus::launch(app);
}
fn app() -> Element {
let mut counters = use_signal(|| vec![0, 0, 0]);
let sum = use_memo(move || counters.read().iter().copied().sum::<i32>());
rsx! {
div { id: "controls",
button { onclick: move |_| counters.push(0), "Add counter" }
button { onclick: move |_| { counters.pop(); }, "Remove counter" }
}
h3 { "Total: {sum}" }
for (i, counter) in counters.iter().enumerate() {
li { key: "{i}",
button { onclick: move |_| counters.write()[i] -= 1, "-1" }
input {
r#type: "number",
value: "{counter}",
oninput: move |e| {
if let Ok(value) = e.parsed() {
counters.write()[i] = value;
}
}
}
button { onclick: move |_| counters.write()[i] += 1, "+1" }
}
}
}
}
중요한 패턴 :
Dioxus는 자동으로 대상 플랫폼을 감지하지만, 실행 구성을 지정할 수도 있습니다.
use dioxus::prelude::*;
fn main() {
dioxus::LaunchBuilder::desktop()
.with_cfg(desktop!({
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
Config::new().with_window(
WindowBuilder::default()
.with_title("My App")
.with_inner_size(LogicalSize::new(800.0, 600.0)),
)
}))
.launch(app);
}
use dioxus::prelude::*;
fn main() {
dioxus::launch(app); // Automatically uses web platform when web feature is enabled
}
앱이 커짐에 따라 코드를 재사용 가능한 구성 요소로 구성하고 싶을 것입니다.
use dioxus::prelude::*;
#[component]
fn Counter(initial_value: i32) -> Element {
let mut count = use_signal(|| initial_value);
rsx! {
div { class: "counter",
h3 { "Count: {count}" }
button { onclick: move |_| count += 1, "+" }
button { onclick: move |_| count -= 1, "-" }
}
}
}
fn app() -> Element {
rsx! {
div {
h1 { "My App" }
Counter { initial_value: 10 }
Counter { initial_value: 20 }
}
}
}
일반적인 Dioxus 프로젝트는 다음 구조를 따릅니다.
my-dioxus-app/
├── Cargo.toml ├── src/
│ ├── main.rs # Application entry point
│ ├── components/ # Reusable components
│ └── assets/ # Static assets
└── public/ # Public files (CSS, images)
rsx! {
button {
onclick: move |_| println!("Clicked!"),
"Click me"
}
input {
oninput: move |e| {
let value: String = e.value();
println!("Input: {value}");
}
}
}
Dioxus는 다음과 같은 자산을 통해 CSS를 지원합니다.
use dioxus::prelude::*;
const STYLE: Asset = asset!("/assets/main.css");
fn app() -> Element {
rsx! {
Stylesheet { href: STYLE }
div { class: "container",
h1 { "Styled Content" }
}
}
}
목록을 렌더링할 때는 항상 안정적인 key 속성을 제공하세요. 배열 인덱스를 키로 사용하면 항목의 순서가 변경되거나 삭제될 때 성능 문제가 발생할 수 있습니다. 대신 데이터의 고유 식별자를 사용하세요.