mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
* change suffixes from md to mdx fix broken links for English locale tree shake and update docusaurus add docusaurus ideal image plugin use svg and themed image delete unused static asset * move localized landing page * change GitLocalize project page * nit pick * remove ignore to have the block checked
243 lines
5.5 KiB
Plaintext
243 lines
5.5 KiB
Plaintext
---
|
|
title: "Elements"
|
|
description: "Both HTML and SVG elements are supported"
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
## DOM nodes
|
|
|
|
There are many reasons why you might want to create or manage DOM nodes manually in Yew, such as
|
|
when integrating with JS libraries that can cause conflicts with managed components.
|
|
|
|
Using `web-sys`, you can create DOM elements and convert them into a `Node` - which can then be
|
|
used as a `Html` value using `VRef`:
|
|
|
|
```rust
|
|
use web_sys::{Element, Node};
|
|
use yew::{Component, Context, html, Html};
|
|
use gloo_utils::document;
|
|
|
|
struct Comp;
|
|
|
|
impl Component for Comp {
|
|
type Message = ();
|
|
type Properties = ();
|
|
|
|
fn create(_ctx: &Context<Self>) -> Self {
|
|
Self
|
|
}
|
|
|
|
fn view(&self, _ctx: &Context<Self>) -> Html {
|
|
// Create a div element from the document
|
|
let div: Element = document().create_element("div").unwrap();
|
|
// Add content, classes etc.
|
|
div.set_inner_html("Hello, World!");
|
|
// Convert Element into a Node
|
|
let node: Node = div.into();
|
|
// Return that Node as a Html value
|
|
Html::VRef(node)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Dynamic tag names
|
|
|
|
When building a higher-order component you might find yourself in a situation where the element's tag name isn't static.
|
|
For example, you might have a `Title` component which can render anything from `h1` to `h6` depending on a level prop.
|
|
Instead of having to use a big match expression, Yew allows you to set the tag name dynamically
|
|
using `@{name}` where `name` can be any expression that returns a string.
|
|
|
|
```rust
|
|
use yew::html;
|
|
|
|
let level = 5;
|
|
let text = "Hello World!".to_owned();
|
|
|
|
html! {
|
|
<@{format!("h{}", level)} class="title">{ text }</@>
|
|
};
|
|
```
|
|
|
|
## Boolean Attributes
|
|
|
|
Some content attributes (e.g checked, hidden, required) are called boolean attributes. In Yew,
|
|
boolean attributes need to be set to a bool value:
|
|
|
|
```rust
|
|
use yew::html;
|
|
|
|
html! {
|
|
<div hidden=true>
|
|
{ "This div is hidden." }
|
|
</div>
|
|
};
|
|
```
|
|
|
|
This will result in **HTML** that's functionally equivalent to this:
|
|
|
|
```html
|
|
<div hidden>This div is hidden.</div>
|
|
```
|
|
|
|
Setting a boolean attribute to false is equivalent to not using the attribute at all; values from
|
|
boolean expressions can be used:
|
|
|
|
```rust
|
|
use yew::html;
|
|
|
|
let no = 1 + 1 != 2;
|
|
|
|
html! {
|
|
<div hidden={no}>
|
|
{ "This div is NOT hidden." }
|
|
</div>
|
|
};
|
|
```
|
|
|
|
This will result in the following **HTML**:
|
|
|
|
```html
|
|
<div>This div is NOT hidden.</div>
|
|
```
|
|
|
|
## Optional attributes for HTML elements
|
|
|
|
Most HTML attributes can use optional values (Some(x) or None). This allows us to omit the attribute if the attribute is marked as optional.
|
|
|
|
```rust
|
|
use yew::html;
|
|
|
|
let maybe_id = Some("foobar");
|
|
|
|
html! {
|
|
<div id={maybe_id}></div>
|
|
};
|
|
```
|
|
|
|
If the attribute is set to `None`, the attribute won't be set in the DOM.
|
|
|
|
## Listeners
|
|
|
|
Listener attributes need to be passed a `Callback` which is a wrapper around a closure. How you create your callback depends on how you wish your app to react to a listener event:
|
|
|
|
<Tabs>
|
|
<TabItem value="Component handler" label="Component handler">
|
|
|
|
```rust
|
|
use yew::{Component, Context, html, Html};
|
|
|
|
struct MyComponent;
|
|
|
|
enum Msg {
|
|
Click,
|
|
}
|
|
|
|
impl Component for MyComponent {
|
|
type Message = Msg;
|
|
type Properties = ();
|
|
|
|
fn create(_ctx: &Context<Self>) -> Self {
|
|
Self
|
|
}
|
|
|
|
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
match msg {
|
|
Msg::Click => {
|
|
// Handle Click
|
|
}
|
|
};
|
|
true
|
|
}
|
|
|
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
// Create a callback from a component link to handle it in a component
|
|
let click_callback = ctx.link().callback(|_| Msg::Click);
|
|
html! {
|
|
<button onclick={click_callback}>
|
|
{ "Click me!" }
|
|
</button>
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="Agent Handler" label="Agent Handler">
|
|
|
|
```rust
|
|
use yew::{html, Component, Context, Html};
|
|
use yew_agent::{Dispatcher, Dispatched};
|
|
use website_test::agents::{MyWorker, WorkerMsg};
|
|
|
|
struct MyComponent {
|
|
worker: Dispatcher<MyWorker>,
|
|
}
|
|
|
|
impl Component for MyComponent {
|
|
type Message = WorkerMsg;
|
|
type Properties = ();
|
|
|
|
fn create(_ctx: &Context<Self>) -> Self {
|
|
MyComponent {
|
|
worker: MyWorker::dispatcher(),
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
self.worker.send(msg);
|
|
false
|
|
}
|
|
|
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
// Create a callback from a worker to handle it in another context
|
|
let click_callback = ctx.link().callback(|_| WorkerMsg::Process);
|
|
html! {
|
|
<button onclick={click_callback}>
|
|
{ "Click me!" }
|
|
</button>
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="Other Cases" label="Other Cases">
|
|
|
|
```rust
|
|
use yew::{Callback, Context, Component, html, Html};
|
|
use weblog::console_log;
|
|
|
|
struct MyComponent;
|
|
|
|
impl Component for MyComponent {
|
|
type Message = ();
|
|
type Properties = ();
|
|
|
|
fn create(_ctx: &Context<Self>) -> Self {
|
|
MyComponent
|
|
}
|
|
|
|
fn view(&self, _ctx: &Context<Self>) -> Html {
|
|
// Create an ephemeral callback
|
|
let click_callback = Callback::from(|_| {
|
|
console_log!("clicked!");
|
|
});
|
|
|
|
html! {
|
|
<button onclick={click_callback}>
|
|
{ "Click me!" }
|
|
</button>
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
## Relevant examples
|
|
|
|
- [Inner HTML](https://github.com/yewstack/yew/tree/master/examples/inner_html)
|