如何用 yew 查询和更新 DOM?

Ali*_*ham 2 rust reactjs yew web-sys

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

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>
    }
}

Run Code Online (Sandbox Code Playgroud)

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

目标2:innerHtml当用户在元素中写入内容时,我还需要更新contenteditable。例如,当用户输入时@john smith,我将创建一个<a>元素,其中包含指向 的个人资料的href链接。John smith

Jul*_*gys 5

你的问题有很多事情需要解决。

#1 不要设置内部html

有关此内容的更多内容,请参阅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();
Run Code Online (Sandbox Code Playgroud)

#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>
    }
}
Run Code Online (Sandbox Code Playgroud)

#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);
Run Code Online (Sandbox Code Playgroud)