You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Yew组件属性值传递给点击处理回调?

Yew组件编译错误修复:解决key不在作用域的问题

我是Rust(及Yew框架)新手,已经写了部分组件,但还没完全搞懂组件生命周期和Rust的生命周期概念(虽然已经看过文档和Stack Overflow的相关回答)。我做了一个接收字符串属性的组件,这个组件会渲染一个按钮,显示传入的字符串,点击按钮时把这个字符串传给处理函数;如果字符串为空,就用指定的默认值。所有宏都来自Yew框架,现在碰到了编译错误:

2024-06-04T16:01:07.169827Z  INFO 🚀 Starting trunk 0.20.1
2024-06-04T16:01:07.262038Z  INFO 📦 starting build
   Compiling trunk-template v0.1.0 (/Users/micah/dev/col)
error[E0425]: cannot find value `key` in this scope
  --> src/user_components.rs:50:44
   |
50 |                 move |_| handle_click.emit(key.as_str() )
   |                                            ^^^ not found in this scope

error[E0425]: cannot find value `key` in this scope
  --> src/user_components.rs:53:34
   |
53 |             {format!("Clear {}", key )}
   |                                  ^^^ not found in this scope

For more information about this error, try `rustc --explain E0425`.
error: could not compile `trunk-template` (bin "trunk-template") due to 2 previous errors
2024-06-04T16:01:08.587588Z ERROR ❌ error
error from build pipeline

Caused by:
    0: HTML build pipeline failed (1 errors), showing first
    1: error from asset pipeline
    2: running cargo build
    3: error during cargo build execution
    4: cargo call to executable 'cargo' with args: '["build", "--target=wasm32-unknown-unknown", "--manifest-path", "/Users/micah/dev/col/Cargo.toml"]' returned a bad status: exit status: 101
2024-06-04T16:01:08.587904Z  INFO 📡 serving static assets at -> /
2024-06-04T16:01:08.588040Z  INFO 📡 server listening at:
2024-06-04T16:01:08.588045Z  INFO     🏠 http://127.0.0.1:9390/
2024-06-04T16:01:08.588048Z  INFO     🏠 http://[::1]:9390/

相关代码如下:

fn create_storage_default() -> AttrValue {
    AttrValue::from( ALL_STORAGE )
}
#[derive(Properties, PartialEq)]
pub struct ClearProps {
    #[prop_or_else( create_storage_default )]
    pub key: AttrValue,
}
const ALL_STORAGE: &str = "all storage";

#[function_component(ClearKey)]
pub fn clear_storage(props: &ClearProps) -> Html {

    let key_string = props.key.clone();

    let handle_click = Callback::from( move |key: &str| {
        match key{
            ALL_STORAGE => LocalStorage::clear(),
            _ => LocalStorage::delete(key)
        }
    } );

    html! {
        <button
            onclick={
                let handle_click = handle_click.clone();
                move |_| handle_click.emit(key.as_str() )
                }
        >
            {format!("Clear {}", key )}
        </button>
    }
}    

错误原因

你在html!宏的onclick闭包和按钮文本中直接使用了key,但当前作用域并没有这个变量——你之前已经把props.key克隆为key_string,但没在这些地方引用它;另外,回调函数的参数也叫key,这个参数只在回调内部有效,和组件属性的key不是同一个变量,容易混淆作用域。

修复后的代码

fn create_storage_default() -> AttrValue {
    AttrValue::from(ALL_STORAGE)
}
#[derive(Properties, PartialEq)]
pub struct ClearProps {
    #[prop_or_else(create_storage_default)]
    pub key: AttrValue,
}
const ALL_STORAGE: &str = "all storage";

#[function_component(ClearKey)]
pub fn clear_storage(props: &ClearProps) -> Html {
    let key_string = props.key.clone();

    let handle_click = Callback::from(move |target_key: &str| {
        match target_key {
            ALL_STORAGE => LocalStorage::clear(),
            _ => LocalStorage::delete(target_key)
        }
    });

    html! {
        <button
            onclick={
                let handle_click = handle_click.clone();
                let key_string = key_string.clone();
                move |_| handle_click.emit(key_string.as_str())
            }
        >
            {format!("Clear {}", key_string)}
        </button>
    }
}

修复说明

  1. 替换变量引用:把按钮文本和onclick闭包里的key都换成之前克隆的key_string,确保作用域正确。
  2. 克隆变量到闭包作用域:在onclick的闭包前克隆key_string,因为move闭包会获取变量所有权,如果不克隆,外层的key_string会被移动,导致按钮文本无法使用。
  3. 重命名回调参数:把回调的参数从key改成target_key,避免和组件属性的变量名混淆,减少作用域误解。

内容的提问来源于stack exchange,提问作者Micah Gideon Modell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:41:04