wip: update readme
This commit is contained in:
1 parent
55e6dd9701
commit
9bd56ee499
4 files changed
+149
-23
No files matched your search
@@ -199,6 +199,149 @@ You shouldn't use Dioxus if:
|
|||||||
- You want to support browsers where Wasm or asm.js are not supported.
|
- You want to support browsers where Wasm or asm.js are not supported.
|
||||||
|
|
||||||
|
|
||||||
|
## Show me some examples!
|
||||||
|
|
||||||
|
In our collection of examples, guides, and tutorials, we have:
|
||||||
|
- The book (an introductory course)
|
||||||
|
- The guide (an in-depth analysis of everything in Dioxus)
|
||||||
|
- The reference (a collection of examples with heavy documentation)
|
||||||
|
- The general examples
|
||||||
|
- The platform-specific examples (web, ssr, desktop, mobile, server)
|
||||||
|
|
||||||
|
Here's what a few common tasks look like in Dioxus:
|
||||||
|
|
||||||
|
Nested components with children and internal state:
|
||||||
|
```rust
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
cx.render(rsx!( Toggle { "Toggle me" } ))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Props)]
|
||||||
|
struct ToggleProps { children: Element }
|
||||||
|
|
||||||
|
fn Toggle(cx: Context, props: &ToggleProps) -> Element {
|
||||||
|
let mut toggled = use_state(cx, || false);
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
{&props.children}
|
||||||
|
button { onclick: move |_| toggled.set(true),
|
||||||
|
{toggled.and_then(|| "On").or_else(|| "Off")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Controlled inputs:
|
||||||
|
```rust
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
let value = use_state(cx, String::new);
|
||||||
|
cx.render(rsx!(
|
||||||
|
input {
|
||||||
|
"type": "text",
|
||||||
|
value: "{value}",
|
||||||
|
oninput: move |evt| value.set(evt.value.clone())
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Lists and Conditional rendering:
|
||||||
|
```rust
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
let list = (0..10).map(|i| {
|
||||||
|
rsx!(li { key: "{i}", "Value: {i}" })
|
||||||
|
});
|
||||||
|
|
||||||
|
let title = match list.len() {
|
||||||
|
0 => rsx!("Not enough"),
|
||||||
|
_ => rsx!("Plenty!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_show {
|
||||||
|
cx.render(rsx!(
|
||||||
|
{title}
|
||||||
|
ul { {list} }
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tiny components:
|
||||||
|
```rust
|
||||||
|
static App: FC<()> = |cx, _| rsx!(cx, div {"hello world!"});
|
||||||
|
```
|
||||||
|
|
||||||
|
Borrowed prop contents:
|
||||||
|
```rust
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
let name = use_state(cx, || String::from("example"));
|
||||||
|
rsx!(cx, Child { title: name.as_str() })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Props)]
|
||||||
|
struct ChildProps<'a> { title: &'a str }
|
||||||
|
|
||||||
|
fn Child(cx: Context, props: &ChildProps) -> Element {
|
||||||
|
rsx!(cx, "Hello {props.title}")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Global State
|
||||||
|
```rust
|
||||||
|
struct GlobalState { name: String }
|
||||||
|
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
use_provide_shared_state(cx, || GlobalState { name: String::from("Toby") })
|
||||||
|
rsx!(cx, Leaf {})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn Leaf(cx: Context, props: &()) -> Element {
|
||||||
|
let state = use_consume_shared_state::<GlobalState>(cx)?;
|
||||||
|
rsx!(cx, "Hello {state.name}")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Router (inspired by Yew-Router)
|
||||||
|
```rust
|
||||||
|
#[derive(PartialEq, Clone, Hash, Eq, Routable)]
|
||||||
|
enum Route {
|
||||||
|
#[at("/")]
|
||||||
|
Home,
|
||||||
|
#[at("/post/{id}")]
|
||||||
|
Post(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
let route = use_router(cx, Route::parse);
|
||||||
|
cx.render(rsx!(div {
|
||||||
|
{match route {
|
||||||
|
Route::Home => rsx!( Home {} ),
|
||||||
|
Route::Post(id) => rsx!( Post { id: id })
|
||||||
|
}}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Suspense
|
||||||
|
```rust
|
||||||
|
fn App(cx: Context, props: &()) -> Element {
|
||||||
|
let doggo = use_suspense(cx,
|
||||||
|
|| async { reqwest::get("https://dog.ceo/api/breeds/image/random").await.unwrap().json::<Response>().await.unwrap() },
|
||||||
|
|response| cx.render(rsx!( img { src: "{response.message}" }))
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
"One doggo coming right up:"
|
||||||
|
{doggo}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the [MIT license].
|
This project is licensed under the [MIT license].
|
||||||
|
|||||||
@@ -365,7 +365,6 @@ impl<'bump> DiffState<'bump> {
|
|||||||
|
|
||||||
fn create_text_node(&mut self, vtext: &'bump VText<'bump>, node: &'bump VNode<'bump>) {
|
fn create_text_node(&mut self, vtext: &'bump VText<'bump>, node: &'bump VNode<'bump>) {
|
||||||
let real_id = self.scopes.reserve_node(node);
|
let real_id = self.scopes.reserve_node(node);
|
||||||
let parent = self.stack.element_stack.last().unwrap();
|
|
||||||
|
|
||||||
self.mutations.create_text_node(vtext.text, real_id);
|
self.mutations.create_text_node(vtext.text, real_id);
|
||||||
vtext.dom_id.set(Some(real_id));
|
vtext.dom_id.set(Some(real_id));
|
||||||
@@ -413,7 +412,6 @@ impl<'bump> DiffState<'bump> {
|
|||||||
let real_id = self.scopes.reserve_node(node);
|
let real_id = self.scopes.reserve_node(node);
|
||||||
self.stack.element_stack.push(real_id);
|
self.stack.element_stack.push(real_id);
|
||||||
dom_id.set(Some(real_id));
|
dom_id.set(Some(real_id));
|
||||||
log::debug!("Parent ID for {:?} set to {:?}", real_id, parent_id.get());
|
|
||||||
|
|
||||||
self.mutations.create_element(tag_name, *namespace, real_id);
|
self.mutations.create_element(tag_name, *namespace, real_id);
|
||||||
|
|
||||||
@@ -545,7 +543,7 @@ impl<'bump> DiffState<'bump> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
old: &'bump VText<'bump>,
|
old: &'bump VText<'bump>,
|
||||||
new: &'bump VText<'bump>,
|
new: &'bump VText<'bump>,
|
||||||
old_node: &'bump VNode<'bump>,
|
_old_node: &'bump VNode<'bump>,
|
||||||
new_node: &'bump VNode<'bump>,
|
new_node: &'bump VNode<'bump>,
|
||||||
) {
|
) {
|
||||||
if let Some(root) = old.dom_id.get() {
|
if let Some(root) = old.dom_id.get() {
|
||||||
|
|||||||
@@ -261,9 +261,7 @@ pub struct VAnchor {
|
|||||||
/// A bump-allocated string slice and metadata.
|
/// A bump-allocated string slice and metadata.
|
||||||
pub struct VText<'src> {
|
pub struct VText<'src> {
|
||||||
pub text: &'src str,
|
pub text: &'src str,
|
||||||
|
|
||||||
pub dom_id: Cell<Option<ElementId>>,
|
pub dom_id: Cell<Option<ElementId>>,
|
||||||
|
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,20 +274,12 @@ pub struct VFragment<'src> {
|
|||||||
/// An element like a "div" with children, listeners, and attributes.
|
/// An element like a "div" with children, listeners, and attributes.
|
||||||
pub struct VElement<'a> {
|
pub struct VElement<'a> {
|
||||||
pub tag_name: &'static str,
|
pub tag_name: &'static str,
|
||||||
|
|
||||||
pub namespace: Option<&'static str>,
|
pub namespace: Option<&'static str>,
|
||||||
|
|
||||||
pub key: Option<&'a str>,
|
pub key: Option<&'a str>,
|
||||||
|
|
||||||
pub dom_id: Cell<Option<ElementId>>,
|
pub dom_id: Cell<Option<ElementId>>,
|
||||||
|
|
||||||
// Keep the parent id around so we can bubble events through the tree
|
|
||||||
pub parent_id: Cell<Option<ElementId>>,
|
pub parent_id: Cell<Option<ElementId>>,
|
||||||
|
|
||||||
pub listeners: &'a [Listener<'a>],
|
pub listeners: &'a [Listener<'a>],
|
||||||
|
|
||||||
pub attributes: &'a [Attribute<'a>],
|
pub attributes: &'a [Attribute<'a>],
|
||||||
|
|
||||||
pub children: &'a [VNode<'a>],
|
pub children: &'a [VNode<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use fxhash::FxHashSet;
|
|||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
use std::{any::Any, collections::VecDeque};
|
use std::{any::Any, collections::VecDeque};
|
||||||
@@ -293,6 +292,7 @@ impl VirtualDom {
|
|||||||
|
|
||||||
let mut items = scope.items.borrow_mut();
|
let mut items = scope.items.borrow_mut();
|
||||||
|
|
||||||
|
// really this should just be retain_mut but that doesn't exist yet
|
||||||
while let Some(mut task) = items.tasks.pop() {
|
while let Some(mut task) = items.tasks.pop() {
|
||||||
// todo: does this make sense?
|
// todo: does this make sense?
|
||||||
// I don't usually write futures by hand
|
// I don't usually write futures by hand
|
||||||
@@ -312,9 +312,7 @@ impl VirtualDom {
|
|||||||
scopes_to_clear.push(*fut);
|
scopes_to_clear.push(*fut);
|
||||||
}
|
}
|
||||||
|
|
||||||
for task in unfinished_tasks.drain(..) {
|
items.tasks.extend(unfinished_tasks.drain(..));
|
||||||
items.tasks.push(task);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for scope in scopes_to_clear {
|
for scope in scopes_to_clear {
|
||||||
@@ -461,17 +459,14 @@ impl VirtualDom {
|
|||||||
);
|
);
|
||||||
diff_state.stack.push(DiffInstruction::Diff { new, old });
|
diff_state.stack.push(DiffInstruction::Diff { new, old });
|
||||||
diff_state.stack.scope_stack.push(scopeid);
|
diff_state.stack.scope_stack.push(scopeid);
|
||||||
|
|
||||||
let scope = scopes.get_scope(&scopeid).unwrap();
|
let scope = scopes.get_scope(&scopeid).unwrap();
|
||||||
let container = scope.container;
|
diff_state.stack.element_stack.push(scope.container);
|
||||||
log::debug!("scope {:?} container {:?}", scope.our_arena_idx, container);
|
|
||||||
diff_state.stack.element_stack.push(container);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let work_completed = diff_state.work(&mut deadline);
|
if diff_state.work(&mut deadline) {
|
||||||
|
|
||||||
if work_completed {
|
|
||||||
let DiffState {
|
let DiffState {
|
||||||
mutations,
|
mutations,
|
||||||
seen_scopes,
|
seen_scopes,
|
||||||
|
|||||||
Reference in new issue
Block a user