Rust Yew.rs插件组件

46scxncf  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(110)

我有一些密码。
它工作正常,但我希望这段代码像往常一样工作。当我们点击外部的某个地方或点击内部的链接时,应该关闭浏览器。这个东西怎么落实?如果我不想使用Bootstrap的js,但只有css。

use yew::prelude::*;

#[function_component(App)]
pub fn app() -> Html {
    let is_open = use_state(|| false);

    let onclick = {
        let is_open = is_open.clone();
        Callback::from(move |_| is_open.set(!*is_open))
    };

    html! {
        <main>
            <div class="dropdown">
                <a
                    class={classes!("btn", "btn-secondary", "dropdown-toggle")}
                    href="#" role="button"
                    data-bs-toggle="dropdown"
                    aria-expanded="false"
                    {onclick}
                >
                 {"Dropdown link"}
                </a>

                <ul class={classes!("dropdown-menu", (*is_open).clone().then(|| Some("show")))}>
                 <li><a class="dropdown-item" href="#">{"Action"}</a></li>
                 <li><a class="dropdown-item" href="#">{"Another action"}</a></li>
                 <li><a class="dropdown-item" href="#">{"Something else here"}</a></li>
                </ul>
            </div>
        </main>
    }
}
ecfsfe2w

ecfsfe2w1#

你需要做两件事:
1.将事件处理程序附加到“整个页面”,即body在单击时关闭您的浏览器
1.停止将click事件从您的事件管理器传播到body上的此事件处理程序。否则,事件也将冒泡到body,您将获得一个打开+关闭,实际上不允许您打开事件。
为方便起见,添加以下依赖项:

gloo = "0.10.0"
wasm-bindgen = "0.2.87"

并按如下方式更改组件:

use std::rc::Rc;

use gloo::utils::document;
use wasm_bindgen::{closure::Closure, JsCast};
use yew::prelude::*;

#[function_component(App)]
pub fn app() -> Html {
    let is_open = use_state(|| false);

    let onclick = {
        let is_open = is_open.clone();
        Callback::from(move |e: MouseEvent| {
            e.stop_propagation();
            is_open.set(!*is_open)
        })
    };

    {
        let is_open = is_open.clone();
        // Make a callback function that closes the dropdown
        let close = Rc::new(Closure::<dyn Fn()>::new({
            move || {
                is_open.set(false);
            }
        }));

        // When the component is mounted, attach the event listener to body
        use_effect_with_deps(
            move |_| {
                let body = document().body().unwrap();
                body.add_event_listener_with_callback("click", (*close).as_ref().unchecked_ref())
                    .unwrap();

                // Clean up the event listener when the component is unmounted
                let close_clone = close.clone();
                move || {
                    body.remove_event_listener_with_callback(
                        "click",
                        (*close_clone).as_ref().unchecked_ref(),
                    )
                    .unwrap();
                }
            },
            (),
        );
    }

    html! {
        <main>
            <div class="dropdown">
                <a
                    class={classes!("btn", "btn-secondary", "dropdown-toggle")}
                    href="#" role="button"
                    data-bs-toggle="dropdown"
                    aria-expanded="false"
                    {onclick}
                >
                 {"Dropdown link"}
                </a>

                <ul class={classes!("dropdown-menu", (*is_open).clone().then(|| Some("show")))}>
                 <li><a class="dropdown-item" href="#">{"Action"}</a></li>
                 <li><a class="dropdown-item" href="#">{"Another action"}</a></li>
                 <li><a class="dropdown-item" href="#">{"Something else here"}</a></li>
                </ul>
            </div>
        </main>
    }
}

相关问题