如何将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> } }
修复说明
- 替换变量引用:把按钮文本和onclick闭包里的
key都换成之前克隆的key_string,确保作用域正确。 - 克隆变量到闭包作用域:在onclick的闭包前克隆
key_string,因为move闭包会获取变量所有权,如果不克隆,外层的key_string会被移动,导致按钮文本无法使用。 - 重命名回调参数:把回调的参数从
key改成target_key,避免和组件属性的变量名混淆,减少作用域误解。
内容的提问来源于stack exchange,提问作者Micah Gideon Modell
相关产品推荐
相关产品推荐

