如何用红豆杉查询和更新DOM?

How to query and update the DOM with yew?

有什么方法可以通过 use_node_ref 进行 DOM 操作吗?或者,如何使用红豆杉在 Rust 中做 document.query_selector()

use web_sys::HtmlInputElement;
use yew::{
    function_component, functional::*, html,
    NodeRef, Html
};

#[function_component(UseRef)]
pub fn ref_hook() -> Html {
    let input_ref = use_node_ref();
    let all_editables =  input_ref.query_selector("[contenteditable]")
    web_sys::console::(all_editables)

    html! {
        <div>
            <input ref={input_ref} type="number" />
        </div>
    }
}

目标: 我有一个富文本编辑器应用程序。我有一个像这样 <h1> this is title</h1><p>hello world</> 这样的字符串形式的缩小 html 我需要获取 DOM 并更改 innerHTML 以将其设置为此值。

Goal2: 当用户在 contenteditable 元素中写入内容时,我还需要更新 innerHtml。例如,当用户输入 @john smith 时,我将创建一个带有 href<a> 元素,其中包含 link 到 John smith 的配置文件。

您的问题需要解决很多问题。

#1 不要设置内部 html

更多内容请阅读 Alternative for innerHTML?

而是创建文本节点。 所以使用 web-sys 你会做这样的事情:

let txtNode: Node = window()
    .unwrap_throw()
    .document()
    .unwrap_throw()
    .create_text_node("Hello")
    .dyn_into()
    .unwrap_throw();

myDomElement.append_hild(&txtNode).unwrap_throw();

#2 如何从输入中查询数据

有很多方法可以做到这一点,所以我只告诉你其中一个 - 受控输入

核心思想是将您的输入值保存在 use_state 中,并使用 valueoninput 属性将其与输入元素同步。

#[function_component(ControlledInputComponent)]
pub fn controlled_input_component() -> Html {
    let my_text_handle = use_state(|| "".to_string());
    let my_text = (*my_text_handle).clone();
    
    let handle_input = Callback::from(move |input_event: InputEvent| {
        let event: Event = input_event.dyn_into().unwrap_throw();
        let input_elem: HTMLInputElement = event.target().unwrap_throw().dyn_into().unwrap_throw();
        let value = input_elem.value();
        my_text_handle.set(value); // update as user types
        
    });

    html! {
        <div>
            <input type="text" value={my_text} oninput={handle_input} />
        </div>
    }
}

#3 更新 DOM

**yew 外部,因为您通常应该避免更新由 yew

控制的 DOM

然后您可以使用 use_effec_with_deps 对您的输入更改做出反应并在那里更新您的外部预览

let my_text_handle = use_state(|| "".to_string());
let my_text = (*my_text_handle).clone();

use_effect_with_deps(move |my_text| {
    // run all the code from my tip #1 like:
    // myDomElement.append_hild(&txtNode).unwrap_throw();
    ||{}
}, my_text);