From 41c1bc57610102ff31b48d7c22212977cec41515 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Thu, 24 Nov 2022 19:43:41 +0500 Subject: [PATCH] website version 0.20 --- .../advanced-topics/how-it-works.mdx | 8 + .../advanced-topics/optimizations.mdx | 171 +++++ .../struct-components/callbacks.mdx | 35 + .../struct-components/lifecycle.mdx | 198 ++++++ .../struct-components/properties.mdx | 84 +++ .../struct-components/refs.mdx | 24 + .../version-0.20/concepts/agents.mdx | 56 ++ .../version-0.20/concepts/html/components.mdx | 108 ++++ .../version-0.20/concepts/html/elements.mdx | 373 +++++++++++ .../concepts/html/introduction.mdx | 22 + .../version-0.20/concepts/html/lists.mdx | 60 ++ .../html/literals-and-expressions.mdx | 60 ++ .../version-0.20/concepts/router.mdx | 95 +++ .../getting-started/build-a-sample-app.mdx | 126 ++++ .../version-0.20/getting-started/examples.mdx | 14 + .../version-0.20/more/css.mdx | 18 + .../version-0.20/more/debugging.mdx | 58 ++ .../version-0.20/more/roadmap.mdx | 45 ++ .../version-0.20/more/testing.mdx | 12 + .../advanced-topics/how-it-works.mdx | 7 + .../advanced-topics/optimizations.mdx | 93 +++ .../struct-components/callbacks.mdx | 27 + .../struct-components/lifecycle.mdx | 170 +++++ .../struct-components/properties.mdx | 72 +++ .../struct-components/refs.mdx | 23 + .../version-0.20/concepts/agents.mdx | 40 ++ .../hooks/custom-hooks.mdx | 121 ++++ .../function-components/introduction.mdx | 27 + .../version-0.20/concepts/html/components.mdx | 114 ++++ .../version-0.20/concepts/html/elements.mdx | 264 ++++++++ .../concepts/html/introduction.mdx | 14 + .../version-0.20/concepts/html/lists.mdx | 57 ++ .../html/literals-and-expressions.mdx | 57 ++ .../version-0.20/concepts/router.mdx | 45 ++ .../getting-started/build-a-sample-app.mdx | 87 +++ .../version-0.20/getting-started/examples.mdx | 11 + .../version-0.20/more/css.mdx | 5 + .../version-0.20/more/debugging.mdx | 50 ++ .../version-0.20/more/roadmap.mdx | 39 ++ .../version-0.20/more/testing.mdx | 11 + .../advanced-topics/how-it-works.mdx | 7 + .../advanced-topics/optimizations.mdx | 118 ++++ .../struct-components/callbacks.mdx | 33 + .../struct-components/lifecycle.mdx | 175 +++++ .../struct-components/properties.mdx | 70 ++ .../struct-components/refs.mdx | 26 + .../version-0.20/concepts/agents.mdx | 41 ++ .../version-0.20/concepts/html/components.mdx | 114 ++++ .../version-0.20/concepts/html/elements.mdx | 264 ++++++++ .../concepts/html/introduction.mdx | 14 + .../version-0.20/concepts/html/lists.mdx | 57 ++ .../html/literals-and-expressions.mdx | 57 ++ .../version-0.20/concepts/router.mdx | 81 +++ .../getting-started/build-a-sample-app.mdx | 127 ++++ .../version-0.20/getting-started/examples.mdx | 11 + .../version-0.20/more/css.mdx | 5 + .../version-0.20/more/debugging.mdx | 50 ++ .../version-0.20/more/roadmap.mdx | 44 ++ .../version-0.20/more/testing.mdx | 11 + .../version-0.20/advanced-topics/children.mdx | 255 ++++++++ .../advanced-topics/how-it-works.mdx | 74 +++ .../advanced-topics/immutable.mdx | 24 + .../advanced-topics/optimizations.mdx | 163 +++++ .../version-0.20/advanced-topics/portals.mdx | 64 ++ .../advanced-topics/server-side-rendering.md | 196 ++++++ .../struct-components/callbacks.mdx | 86 +++ .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 32 + .../struct-components/lifecycle.mdx | 305 +++++++++ .../struct-components/properties.mdx | 145 +++++ .../struct-components/refs.mdx | 55 ++ .../struct-components/scope.mdx | 81 +++ .../version-0.20/concepts/agents.mdx | 64 ++ .../concepts/basic-web-technologies/css.mdx | 101 +++ .../concepts/basic-web-technologies/html.mdx | 79 +++ .../concepts/basic-web-technologies/js.mdx | 53 ++ .../basic-web-technologies/wasm-bindgen.mdx | 243 +++++++ .../basic-web-technologies/web-sys.mdx | 245 +++++++ .../version-0.20/concepts/contexts.mdx | 174 +++++ .../function-components/callbacks.mdx | 74 +++ .../concepts/function-components/children.mdx | 41 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 113 ++++ .../hooks/introduction.mdx | 51 ++ .../function-components/introduction.mdx | 76 +++ .../function-components/node-refs.mdx | 21 + .../function-components/properties.mdx | 300 +++++++++ .../function-components/pure-components.mdx | 39 ++ .../concepts/function-components/state.mdx | 26 + .../version-0.20/concepts/html/classes.mdx | 130 ++++ .../version-0.20/concepts/html/components.mdx | 172 +++++ .../concepts/html/conditional-rendering.mdx | 73 +++ .../version-0.20/concepts/html/elements.mdx | 145 +++++ .../version-0.20/concepts/html/events.mdx | 601 +++++++++++++++++ .../version-0.20/concepts/html/fragments.mdx | 43 ++ .../concepts/html/introduction.mdx | 222 +++++++ .../version-0.20/concepts/html/lists.mdx | 125 ++++ .../html/literals-and-expressions.mdx | 71 +++ .../version-0.20/concepts/router.mdx | 505 +++++++++++++++ .../version-0.20/concepts/suspense.mdx | 181 ++++++ .../getting-started/build-a-sample-app.mdx | 141 ++++ .../getting-started/editor-setup.mdx | 133 ++++ .../version-0.20/getting-started/examples.mdx | 17 + .../getting-started/introduction.mdx | 53 ++ .../yew-agent/from-0_0_0-to-0_1_0.mdx | 7 + .../yew-agent/from-0_1_0-to-0_2_0.mdx | 23 + .../yew-router/from-0_15_0-to-0_16_0.mdx | 9 + .../yew-router/from-0_16_0-to-0_17_0.mdx | 12 + .../yew/from-0_18_0-to-0_19_0.mdx | 139 ++++ .../yew/from-0_19_0-to-0_20_0.mdx | 84 +++ .../versioned_docs/version-0.20/more/css.mdx | 29 + .../version-0.20/more/debugging.mdx | 100 +++ .../version-0.20/more/deployment.mdx | 45 ++ .../version-0.20/more/roadmap.mdx | 44 ++ .../version-0.20/more/testing.mdx | 25 + .../version-0.20/tutorial/index.mdx | 603 ++++++++++++++++++ .../version-0.20-sidebars.json | 177 +++++ website/versions.json | 6 +- 119 files changed, 11437 insertions(+), 1 deletion(-) create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/lists.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/router.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/getting-started/examples.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/more/css.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/more/debugging.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/more/roadmap.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/more/testing.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/function-components/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/html/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/html/lists.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/concepts/router.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/getting-started/examples.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/more/css.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/more/debugging.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/more/roadmap.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.20/more/testing.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/html/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/html/lists.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/concepts/router.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/getting-started/examples.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/more/css.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/more/debugging.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/more/roadmap.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.20/more/testing.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/children.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/how-it-works.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/immutable.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/optimizations.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/portals.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/server-side-rendering.md create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/hoc.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/introduction.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/properties.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/refs.mdx create mode 100644 website/versioned_docs/version-0.20/advanced-topics/struct-components/scope.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/agents.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/basic-web-technologies/css.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/basic-web-technologies/html.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/basic-web-technologies/js.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/contexts.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/callbacks.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/children.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/communication.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/generics.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/hooks/introduction.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/introduction.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/node-refs.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/properties.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/pure-components.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/function-components/state.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/classes.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/components.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/conditional-rendering.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/elements.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/events.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/fragments.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/introduction.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/lists.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/html/literals-and-expressions.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/router.mdx create mode 100644 website/versioned_docs/version-0.20/concepts/suspense.mdx create mode 100644 website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx create mode 100644 website/versioned_docs/version-0.20/getting-started/editor-setup.mdx create mode 100644 website/versioned_docs/version-0.20/getting-started/examples.mdx create mode 100644 website/versioned_docs/version-0.20/getting-started/introduction.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew-agent/from-0_0_0-to-0_1_0.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew-router/from-0_15_0-to-0_16_0.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew-router/from-0_16_0-to-0_17_0.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew/from-0_18_0-to-0_19_0.mdx create mode 100644 website/versioned_docs/version-0.20/migration-guides/yew/from-0_19_0-to-0_20_0.mdx create mode 100644 website/versioned_docs/version-0.20/more/css.mdx create mode 100644 website/versioned_docs/version-0.20/more/debugging.mdx create mode 100644 website/versioned_docs/version-0.20/more/deployment.mdx create mode 100644 website/versioned_docs/version-0.20/more/roadmap.mdx create mode 100644 website/versioned_docs/version-0.20/more/testing.mdx create mode 100644 website/versioned_docs/version-0.20/tutorial/index.mdx create mode 100644 website/versioned_sidebars/version-0.20-sidebars.json diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx new file mode 100644 index 00000000000..c0a15e94326 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/how-it-works.mdx @@ -0,0 +1,8 @@ +--- +title: How it works +description: Low level details about the framework +--- + +# 低レベルなライブラリの中身 + +コンポーネントのライフサイクルの状態機械、VDOM の異なるアルゴリズム diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx new file mode 100644 index 00000000000..d9db08c0fa9 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/optimizations.mdx @@ -0,0 +1,171 @@ +--- +title: Optimizations +description: Make your app faster +--- + +# 最適化とベストプラクティス + +## neq_assign + +親コンポーネントから props を受け取った際、`change`メソッドが呼ばれます。 +これはコンポーネントの状態を更新することができるのに加え、コンポーネントが props が変わった際に再レンダリングするかどうかを決める +`ShouldRender`という真偽値を返すことができます。 + +再レンダリングはコストがかかるもので、もし避けられるのであれば避けるべきです。 +一般的なルールとして props が実際に変化した際にのみ再レンダリングすれば良いでしょう。 +以下のコードブロックはこのルールを表しており、props が前と変わったときに`true`を返します。 + +```rust +use yew::ShouldRender; + +#[derive(PartialEq)] +struct ExampleProps; + +struct Example { + props: ExampleProps, +}; + +impl Example { + fn change(&mut self, props: ExampleProps) -> ShouldRender { + if self.props != props { + self.props = props; + true + } else { + false + } + } +} +``` + +しかし我々は先に進んでいけます! +この 6 行のボイラープレードは`PartialEq`を実装したものにトレイトとブランケットを用いることで 1 行のコードへと落とし込むことができます。 +[こちら](https://docs.rs/yewtil/*/yewtil/trait.NeqAssign.html)にて`yewtil`クレートの`NewAssign`トレイトを見てみてください。 + +## 効果的にスマートポインタを使う + +**注意: このセクションで使われている用語がわからなければ Rust book は +[スマートポインタについての章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) +があり、非常に有用です。** + +再レンダリングの際に props を作るデータを大量にコピーしないために、スマートポインタを用いてデータ自体ではなくデータへの参照だけを +コピーできます。 +props や子コンポーネントで関連するデータに実データではなく参照を渡すと、子コンポーネントでデータを変更する必要がなければ +データのコピーを避けることができます。 +その際、`Rc::make_mut`によって変更したいデータの変更可能な参照を得ることができます。 + +これにより、props が変更されたときにコンポーネントが再レンダリングされるかどうかを決めるかで`Component::change`に更なる恩恵があります。 +なぜなら、データの値を比較する代わりに元々のポインタのアドレス (つまりデータが保管されている機械のメモリの場所) を比較できるためです。 +2 つのポインターが同じデータを指す場合、それらのデータの値は同じでなければならないのです。 +ただし、その逆は必ずしも成り立たないことに注意してください! +もし 2 つのポインタが異なるのであれば、そのデータは同じである可能性があります。 +この場合はデータを比較するべきでしょう。 + +この比較においては`PartialEq`ではなく`Rc::ptr_eq`を使う必要があります。 +`PartialEq`は等価演算子`==`を使う際に自動的に使われます。 +Rust のドキュメントには[`Rc::ptr_eq`についてより詳しく書いてあります](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.ptr_eq)。 + +この最適化は`Copy`を実装していないデータの型に対して極めて有効なものです。 +もしデータを簡単に変更できるのであれば、スマートポインタに取り換える必要はありません。 +しかし`Vec`や`HashMap`、`String`などのような重たいデータの構造体に対してはスマートポインタを使うことで +パフォーマンスを改善することができるでしょう。 + +この最適化は値がまだ一度も子によって更新されていない場合に極めて有効で、親からほとんど更新されない場合においてもかなり有効です。 +これにより、`Rc<_>s`が純粋なコンポーネントに対してプロパティの値をラップする良い一手となります。 + +## View 関数 + +コードの可読性の理由から`html!`の部分を関数へと移植するのは意味があります。 +これは、インデントを減らすのでコードを読みやすくするだけでなく、良いデザインパターンを産むことにも繋がるのです。 +これらの関数は複数箇所で呼ばれて書くべきコード量を減らせるため、分解可能なアプリケーションを作ることができるのです。 + +## 純粋なコンポーネント + +純粋なコンポーネントは状態を変化せず、ただ中身を表示してメッセージを普通の変更可能なコンポーネントへ渡すコンポーネントのことです。 +View 関数との違いとして、純粋なコンポーネントは式の構文\(`{some_view_function()}`\)ではなく +コンポーネントの構文\(``\)を使うことで`html!`マクロの中で呼ばれる点、 +そして実装次第で記憶され (つまり、一度関数が呼ばれれば値は"保存"され、 +同じ引数でもう一度呼ばれても値を再計算する必要がなく最初に関数が呼ばれたときの保存された値を返すことができる)、 +先述の`neq_assign`ロジックを使う別々の props で再レンダリングを避けられる点があります。 + +Yew は純粋な関数やコンポーネントをサポートしていませんが、外部のクレートを用いることで実現できます。 + +## 関数型コンポーネント (a.k.a フック) + +関数型コンポーネントはまだ開発中です! +開発状況については[プロジェクトボード](https://github.com/yewstack/yew/projects/3)に詳しく書いてあります。 + +## キー付き DOM ノード + +## ワークスペースでコンパイル時間を減らす + +間違いなく Yew を使う上での最大の欠点はコンパイルに時間がかかる点です。 +プロジェクトのコンパイルにかかる時間は`html!`マクロに渡されるコードの量に関係しています。 +これは小さなプロジェクトにはそこまで問題ないようですが、大きなアプリではコードを複数クレートに分割することでアプリに変更が加られた際に +コンパイラの作業量を減らすのが有効です。 + +一つ可能なやり方として、ルーティングとページ洗濯を担当するメインのクレートを作り、それぞれのページに対して別のクレートを作ることです。 +そうして各ページは異なるコンポーネントか、`Html`を生成する大きな関数となります。 +アプリの異なる部分を含むクレート同士で共有されるコードはプロジェクト全体で依存する分離したクレートに保存されます。 +理想的には 1 回のコンパイルでコード全てを再ビルドせずメインのクレートかどれかのページのクレートを再ビルドするだけにすることです。 +最悪なのは、"共通"のクレートを編集して、はじめに戻ってくることです: +共有のクレートに依存している全てのコード、恐らく全てのコードをコンパイルすることです。 + +もしメインのクレートが重たすぎる、もしくは深くネストしたページ (例えば別ページのトップでレンダリングされるページ) +で速く繰り返したい場合、クレートの例を用いてメインページの実装をシンプルにしたりトップで動かしているコンポーネントをレンダリングできます。 + +## バイナリサイズを小さくする + +- Rust のコードを最適化する +- `cargo.toml` \( release profile を定義 \) +- `wasm-opt`を用いて wasm のコードを最適化する + +**注意: バイナリサイズを小さくするのについては[Rust Wasm Book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)に詳しく書いてあります。** + +### Cargo.toml + +`Cargo.toml`で`[profile.release]`のセクションに設定を書き込むことでリリースビルドを小さくすることが可能です。 + +```text +[profile.release] +# バイナリに含むコードを少なくする +panic = 'abort' +# コードベース全体での最適化 ( 良い最適化だがビルドが遅くなる) +codegen-units = 1 +# サイズの最適化( よりアグレッシブに ) +opt-level = 'z' +# サイズの最適化 +# opt-level = 's' +# プログラム全体の分析によるリンク時最適化 +lto = true +``` + +### wasm-opt + +更に`wasm`のコードのサイズを最適化することができます。 + +The Rust Wasm Book には Wasm バイナリのサイズを小さくすることについてのセクションがあります: +[Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html) + +- `wasm-pack`でデフォルトの`wasm`のコードをリリースビルド時に最適化する +- `wasm-opt`によって直接`wasm`ファイルを最適化する + +```text +wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm +``` + +#### yew/examples/にある例を小さなサイズでビルドする + +注意: `wasm-pack`は Rust と Wasm のコードへの最適化を組み合わせます。`wasm-bindgen`はこの例では Rust のサイズ最適化を用いていません。 + +| 使用したツール | サイズ | +| :-------------------------- | :----- | +| wasm-bindgen | 158KB | +| wasm-bindgen + wasm-opt -Os | 116KB | +| wasm-pack | 99 KB | + +## 参考文献: + +- [The Rust Book のスマートポインタに関する章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) +- [the Rust Wasm Book でのバイナリサイズを小さくすることについて](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size) +- [Rust profiles についてのドキュメント](https://doc.rust-lang.org/cargo/reference/profiles.html) +- [binaryen プロジェクト](https://github.com/WebAssembly/binaryen) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx new file mode 100644 index 00000000000..7799426a3c6 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/callbacks.mdx @@ -0,0 +1,35 @@ +--- +title: Callbacks +description: ComponentLink and Callbacks +--- + +”リンク”コンポーネントはコンポーネントがコールバックを登録できて自身を更新することができるメカニズムです。 + +## ComponentLink API + +### callback + +実行時にコンポーネントの更新メカニズムにメッセージを送信するコールバックを登録します。 +これは、渡されたクロージャから返されるメッセージで `send_self` を呼び出します。 +`Fn(IN) -> Vec`が渡され、`Callback`が返されます。 + +### send_message + +現在のループが終了した直後にコンポーネントにメッセージを送信し、別の更新ループを開始します。 + +### send_message_batch + +実行時に一度に多数のメッセージを一括して送信するコールバックを登録します。 +メッセージによってコンポーネントが再レンダリングされる場合、バッチ内のすべてのメッセージが処理された後、コンポーネントは再レンダリングされます。 +`Fn(IN) -> COMP::Message`が渡され、`Callback`が返されます。 + +## コールバック + +_\(This might need its own short page.\)_ + +コールバックは、Yew 内のサービス、エージェント、親コンポーネントとの通信に使われます。 +これらは単に `Fn` を `Rc` でラップしただけであり、クローンを作成できるようにするためのものです。 + +これらの関数には `emit` 関数があり、`` 型を引数に取り、それをアドレスが欲しいメッセージに変換します。 +親からのコールバックが子コンポーネントに props で提供されている場合、子は `update` ライフサイクルフックで `emit` をコールバックに呼び出して親にメッセージを返すことができます。 +マクロ内で props として提供されたクロージャや関数は自動的にコールバックに変換されます。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx new file mode 100644 index 00000000000..274c3d815d9 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/lifecycle.mdx @@ -0,0 +1,198 @@ +--- +title: Introduction +description: Components and their lifecycle hooks +--- + +## コンポーネントとは? + +コンポーネントは Yew を構成するブロックです。 +コンポーネントは状態を管理し、自身を DOM へレンダリングすることができます。 +コンポーネントはライフサイクルの機能がある`Component`トレイトを実装することによって作られます。 + +## ライフサイクル + +:::important contribute +`Contribute to our docs:` [Add a diagram of the component lifecycle](https://github.com/yewstack/docs/issues/22) +::: + +## ライフサイクルのメソッド + +### Create + +コンポーネントが作られると、`ComponentLink`と同様に親コンポーネントからプロパティを受け取ります。 +プロパティはコンポーネントの状態を初期化するのに使われ、"link"はコールバックを登録したりコンポーネントにメッセージを送るのに使われます。 + +props と link をコンポーネント構造体に格納するのが一般的です。 +例えば: + +```rust +pub struct MyComponent { + props: Props, + link: ComponentLink, +} + +impl Component for MyComponent { + type Properties = Props; + // ... + + fn create(props: Self::Properties, link: ComponentLink) -> Self { + MyComponent { props, link } + } + + // ... +} +``` + +### View + +コンポーネントは`view()`メソッドによってレイアウトを宣言します。 +Yew は`html!`マクロによって HTML と SVG ノード、リスナー、子コンポーネントを宣言できます。 +マクロは React の JSX のような動きをしますが、JavaScript の代わりに Rust の式を用います。 + +```rust +impl Component for MyComponent { + // ... + + fn view(&self) -> Html { + let onclick = self.link.callback(|_| Msg::Click); + html! { + + } + } +} +``` + +使い方については[`html!`ガイド](concepts/html/introduction.mdx)をご確認ください。 + +### Rendered + +`rendered()`コンポーネントのライフサイクルのメソッドは`view()`が処理されたて Yew がコンポーネントをレンダリングした後、 +ブラウザがページを更新する前に呼ばれます。 +コンポーネントは、コンポーネントが要素をレンダリングした後にのみ実行できるアクションを実行するため、このメソッドを実装したい場合があります。 +コンポーネントが初めてレンダリングされたかどうかは `first_render` パラメータで確認できます。 + +```rust +use stdweb::web::html_element::InputElement; +use stdweb::web::IHtmlElement; +use yew::prelude::*; + +pub struct MyComponent { + node_ref: NodeRef, +} + +impl Component for MyComponent { + // ... + + fn view(&self) -> Html { + html! { + + } + } + + fn rendered(&mut self, first_render: bool) { + if first_render { + if let Some(input) = self.node_ref.try_into::() { + input.focus(); + } + } + } +} +``` + +:::tip note +ライフサイクルメソッドは実装の必要がなく、デフォルトでは何もしません。 +::: + +### Update + +コンポーネントは動的で、非同期メッセージを受信するために登録することができます。 +ライフサイクルメソッド `update()` はメッセージごとに呼び出されます。 +これにより、コンポーネントはメッセージが何であったかに基づいて自身を更新し、自身を再レンダリングする必要があるかどうかを判断することができます。 +メッセージは、HTML 要素リスナーによってトリガーされたり、子コンポーネント、エージェント、サービス、または Futures によって送信されたりします。 + +`update()`がどのようなのかについての例は以下の通りです: + +```rust +pub enum Msg { + SetInputEnabled(bool) +} + +impl Component for MyComponent { + type Message = Msg; + + // ... + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::SetInputEnabled(enabled) => { + if self.input_enabled != enabled { + self.input_enabled = enabled; + true // Re-render + } else { + false + } + } + } + } +} +``` + +### Change + +コンポーネントは親によって再レンダリングされることがあります。 +このような場合、新しいプロパティを受け取り、再レンダリングを選択する可能性があります。 +この設計では、プロパティを変更することで、親から子へのコンポーネントの通信が容易になります。 + +典型的な実装例は以下の通りです: + +```rust +impl Component for MyComponent { + // ... + + fn change(&mut self, props: Self::Properties) -> ShouldRender { + if self.props != props { + self.props = props; + true + } else { + false + } + } +} +``` + +### Destroy + +コンポーネントが DOM からアンマウントされた後、Yew は `destroy()` ライフサイクルメソッドを呼び出し、必要なクリーンアップ操作をサポートします。 +このメソッドはオプションで、デフォルトでは何もしません。 + +## Associated Types + +`Component`トレイトは 2 つの関連型があります: `Message`と`Properties`です。 + +```rust +impl Component for MyComponent { + type Message = Msg; + type Properties = Props; + + // ... +} +``` + +`Message`はコンポーネントによって処理され、何らかの副作用を引き起こすことができるさまざまなメッセージを表します。 +例えば、API リクエストをトリガーしたり、UI コンポーネントの外観を切り替えたりする `Click` メッセージがあります。 +コンポーネントのモジュールで `Msg` という名前の列挙型を作成し、それをコンポーネントのメッセージ型として使用するのが一般的です。 +"message"を"msg"と省略するのも一般的です。 + +```rust +enum Msg { + Click, +} +``` + +`Properties`は、親からコンポーネントに渡される情報を表します。 +この型は Properties trait を実装していなければならず\(通常はこれを派生させることで\)、特定のプロパティが必須かオプションかを指定することができます。 +この型は、コンポーネントの作成・更新時に使用されます。 +コンポーネントのモジュール内に `Props` という構造体を作成し、それをコンポーネントの `Properties` 型として使用するのが一般的です。 +”Properties”を"props"に短縮するのが一般的です。 +Props は親コンポーネントから継承されるので、アプリケーションのルートコンポーネントは通常`()`型の`Properties`を持ちます。 +ルートコンポーネントのプロパティを指定したい場合は、`App::mount_with_props`メソッドを利用します。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx new file mode 100644 index 00000000000..560f9c1e6e7 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/properties.mdx @@ -0,0 +1,84 @@ +--- +title: Properties +description: Parent to child communication +--- + +プロパティは、子コンポーネントと親コンポーネントが互いに通信できるようにします。 + +## マクロの継承 + +`Properties`を自分で実装しようとせず、代わりに`#[derive(Properties)]`を使ってください。 + +:::note +`Properties`を継承した型は`Clone`を実装していなければいけません。 +これは`#[derive(Properties, Clone)`か`Clone`を手で実装することで可能です。 +::: + +### 必要な属性 + +デフォルトでは、`Properties` を導出する構造体内のフィールドは必須です。 +フィールドが欠落していて `html!` マクロでコンポーネントが作成された場合、コンパイラエラーが返されます。 +オプションのプロパティを持つフィールドについては、`#[prop_or_default]` 属性を使用して、prop が指定されていない場合はその型のデフォルト値を使用します。 +値を指定するには `#[prop_or(value)]` 属性を用います。 +ここで value はプロパティのデフォルト値、あるいは代わりに `#[prop_or_else(function)]` を使用して、`function` はデフォルト値を返します。 +例えば、ブール値のデフォルトを `true` とするには、属性 `#[prop_or(true)]` を使用します。オプションのプロパティでは、デフォルト値 `None` を持つ `Option` 列挙型を使うのが一般的です。 + +### PartialEq + +もし可能なら props で `PartialEq` を継承するのが良いかもしれません。 +`PartialEq`を使うことで、不必要な再レンダリングを避けることができます +(これについては、**最適化とベストプラクティス**のセクションで説明しています)。 + +## プロパティを使用する際のメモリと速度のオーバーヘッド + +`Compoenent::view`ではコンポーネントの状態への参照を取り、それを使って `Html` を作成します。 +しかし、プロパティは自身の値です。 +つまり、それらを作成して子コンポーネントに渡すためには、`view` 関数で提供される参照を所有する必要があるのです。 +これは所有する値を取得するためにコンポーネントに渡される参照を暗黙のうちにクローンすることで行われます。 + +これは、各コンポーネントが親から受け継いだ状態の独自のコピーを持っていることを意味し、コンポーネントを再レンダリングするときはいつでも、再レンダリングしたコンポーネントのすべての子コンポーネントの props がクローンされなければならないことを意味します。 + +このことの意味するところは、もしそうでなければ*大量の*データ \(10KB もあるような文字列\) を props として渡してしまうのであれば、子コンポーネントを親が呼び出す `Html` を返す関数にすることを考えた方がいいかもしれないということです。 + +props を介して渡されたデータを変更する必要がない場合は、実際のデータそのものではなく、データへの参照カウントされたポインタのみが複製されるように `Rc` でラップすることができます。 + +## 例 + +```rust +use std::rc::Rc; +use yew::Properties; + +#[derive(Clone, PartialEq)] +pub enum LinkColor { + Blue, + Red, + Green, + Black, + Purple, +} + +impl Default for LinkColor { + fn default() -> Self { + // The link color will be blue unless otherwise specified. + LinkColor::Blue + } +} + +#[derive(Properties, Clone, PartialEq)] +pub struct LinkProps { + /// The link must have a target. + href: String, + /// If the link text is huge, this will make copying the string much cheaper. + /// This isn't usually recommended unless performance is known to be a problem. + text: Rc, + /// Color of the link. + #[prop_or_default] + color: LinkColor, + /// The view function will not specify a size if this is None. + #[prop_or_default] + size: Option, + /// When the view function doesn't specify active, it defaults to true. + #[prop_or(true)] + active: bool, +} +``` diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx new file mode 100644 index 00000000000..bfaf178cc4b --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/advanced-topics/struct-components/refs.mdx @@ -0,0 +1,24 @@ +--- +title: Refs +description: Out-of-band DOM access +--- + +`ref`は、任意の HTML 要素やコンポーネントの内部で、割り当てられている DOM`Element`を取得するために使用することができます。 +これは、`view` ライフサイクルメソッドの外で DOM に変更を加えるために使用できます。 + +これは、キャンバスの要素を取得したり、ページの異なるセクションにスクロールしたりするのに便利です。 + +構文は以下の通りです: + +```rust +// In create +self.node_ref = NodeRef::default(); + +// In view +html! { +
+} + +// In update +let has_attributes = self.node_ref.try_into::().has_attributes(); +``` diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx new file mode 100644 index 00000000000..efe31f8efef --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/agents.mdx @@ -0,0 +1,56 @@ +--- +title: Agents +description: Yew's Actor System +--- + +エージェントは Angular の[サービス](https://angular.io/guide/architecture-services)に似ており\(ただし依存性インジェクションはありません\)、 +[アクターモデル](https://en.wikipedia.org/wiki/Actor_model)を提供します。 +エージェントはコンポーネント階層のどこに位置するかに関わらず、コンポーネント間でメッセージをルーティングしたり、共有状態を作成したり、UI をレンダリングするメインスレッドから計算量の多いタスクをオフロードするために使用することができます。 +また、Yew アプリケーションがタブをまたいで通信できるようにするためのエージェントのサポートも\(将来的には\)計画されています。 + +エージェントが並行に動くように Yew は[web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)を使用しています。 + +## ライフサイクル + +![エージェントのライフサイクル](https://user-images.githubusercontent.com/42674621/79125224-b6481d80-7d95-11ea-8e6a-ab9b52d1d8ac.png) + +## エージェントの種類 + +### Reaches + +- Context - Context エージェントのインスタンスは、常に最大 1 つ存在します。 + Bridges は、UI スレッド上で既にスポーンされたエージェントをスポーンするか、接続します。 + これは、コンポーネントまたは他のエージェント間の状態を調整するために使用することができます。 + このエージェントに Bridges が接続されていない場合、このエージェントは消滅します。 + +- Job - 新しいブリッジごとに UI スレッド上で新しいエージェントをスポーンします。 + これは、ブラウザと通信する共有されているが独立した動作をコンポーネントの外に移動させるのに適しています。 + (TODO 確認) タスクが完了すると、エージェントは消えます。 + +- Public - Context と同じですが、独自の web worker で動作します。 + +- Private - Job と同じですが、独自の web worker で動作します。 + +- Global \(WIP\) + +## エージェントとコンポーネントのやり取り + +### Bridges + +Bridge は、エージェントとコンポーネント間の双方向通信を可能にします。 +また、Bridge はエージェント同士の通信を可能にします。 + +### Dispatchers + +Dispatcher は、コンポーネントとエージェント間の一方向通信を可能にします。 +Dispatcher は、コンポーネントがエージェントにメッセージを送信することを可能にします。 + +## オーバーヘッド + +独自の独立した web worker(プライベートとパブリック)にあるエージェントは、送受信するメッセージにシリアライズするオーバーヘッドが発生します。 +他のスレッドとの通信には[bincode](https://github.com/servo/bincode)を使用するので、関数を呼び出すよりもコストはかなり高くなります。 +計算コストがメッセージの受け渡しコストを上回る場合を除き、ロジックを UI スレッドエージェント\(Job または Context\)に格納する必要があります。 + +## 参考資料 + +- [web_worker_fib](https://github.com/yewstack/yew/tree/master/examples/web_worker_fib)の例でコンポーネントがどのようにエージェントと通信させているかがわかります。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx new file mode 100644 index 00000000000..23434dad96c --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/components.mdx @@ -0,0 +1,108 @@ +--- +title: Components +description: Create complex layouts with component hierarchies +--- + +## 基本 + +`Component`を実装しているあらゆる型は`html!`マクロの中で使えます: + +```rust +html!{ + <> + // No properties + + + // With Properties + + + // With the whole set of props provided at once + + + // With Properties from a variable and specific values overridden + + +} +``` + +## ネスト + +`children`フィールドが`Properties`の中にある場合はコンポーネントは子に渡されます。 + +```rust title="parent.rs" +html! { + +

{ "Hi" }

+
{ "Hello" }
+
+} +``` + +```rust title="container.rs" +pub struct Container(Props); + +#[derive(Properties, Clone)] +pub struct Props { + pub children: Children, +} + +impl Component for Container { + type Properties = Props; + + // ... + + fn view(&self) -> Html { + html! { +
+ { self.0.children.clone() } +
+ } + } +} +``` + +:::note +`Properties`を継承した型は`Clone`を実装していなければいけません。 +これは`#[derive(Properties, Clone)]`を使うか手で`Clone`を実装すれば良いです。 +::: + +## Props とネストした子コンポーネント + +ネストしたコンポーネントのプロパティは格納しているコンポーネントの型が子である場合はアクセス可能、または変更可能です。 +以下の例では`List`コンポーネントは`ListItem`コンポーネントをラップできています。 +実際の使用においてこのパターンの例については`yew-router`のソースコードを確認してみてください。 +より進んだ例としては Yew のメインのリポジトリにある`nested-list`を確認してみてください。 + +```rust title="parent.rs" +html! { + + + + + +} +``` + +```rust title="list.rs" +pub struct List(Props); + +#[derive(Properties, Clone)] +pub struct Props { + pub children: ChildrenWithProps, +} + +impl Component for List { + type Properties = Props; + + // ... + + fn view(&self) -> Html { + html!{{ + for self.0.children.iter().map(|mut item| { + item.props.value = format!("item-{}", item.props.value); + item + }) + }} + } +} +``` diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx new file mode 100644 index 00000000000..9bb97e147c2 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-0.20/concepts/html/elements.mdx @@ -0,0 +1,373 @@ +--- +title: Elements +description: Both HTML and SVG elements are supported +--- + +## タグ構造 + +要素のタグは`<... />`のような自己完結タグか、開始タグに対応した終了タグを持っている必要があります。 + + + + +```rust +html! { +
+} +``` + + + +```rust +html! { +
// <- MISSING CLOSE TAG +} +``` + + + +```rust +html! { + +} +``` + + + +```rust +html! { + // <- MISSING SELF-CLOSE +} +``` + + + +:::note +便利さのために、*普通は*終了タグを必要とする要素は自己完結タグとすることが**できます**。 +例えば`html! {
}`と書くのは有効です。 +::: + +## 子 + +複雑にネストした HTML や SVG のレイアウトを書くのには以下のようにするのが楽です: +\*\* + + + + +```rust +html! { +
+
+
+ + + + +