14-6. 执行动作的依据(如:为什么会自动打开风扇、水泵、蜂鸣器等外设)
2026/6/9 4:10:00
on_click参数,可以为按钮指定点击时执行的函数。该参数接收一个可调用对象(如函数或 lambda 表达式),并在事件发生时异步执行。from nicegui import ui def button_clicked(): print("按钮被点击了!") # 绑定事件 ui.button('点击我', on_click=button_clicked) ui.run()上述代码中,button_clicked函数在按钮被点击时输出提示信息。注意:函数名后不加括号,传递的是函数引用而非立即调用。ui.button('增加计数', on_click=lambda: print("计数 +1"))这种方式适用于无需复用的短逻辑,提升代码紧凑性。| 场景 | 实现方式 | 说明 |
|---|---|---|
| 更新文本 | label.set_text() | 动态改变标签内容 |
| 控制可见性 | element.visible = False | 隐藏或显示组件 |
| 禁用按钮 | button.disable() | 防止重复提交 |
async def定义addEventListener可绑定“click”事件:const button = document.getElementById('submit-btn'); button.addEventListener('click', function(event) { console.log('按钮被点击'); });上述代码中,event参数包含事件详情,如触发元素(event.target)和时间戳(event.timeStamp)。浏览器在检测到鼠标按下并释放在同一可交互元素上时,才会派发 click 事件。event.stopPropagation()阻止后续传播,避免意外触发父级行为。def handle_click(): print("按钮被点击了!") button.on_click(handle_click)上述代码中,`handle_click` 为无参回调函数,`on_click` 将其注册为监听器。注意不加括号以传递函数引用而非调用结果。// 同步调用:阻塞等待结果 const result = fetchDataSync(); console.log(result); // 必须等待完成 // 异步调用:非阻塞,使用回调 fetchDataAsync((data) => { console.log(data); // 响应就绪后触发 });上述代码中,同步方式逻辑直观但影响性能;异步方式提升响应性,但需处理回调地狱或使用 async/await 优化流程。const submitBtn = document.getElementById('submit'); let isLoading = false; function toggleButton() { submitBtn.disabled = isLoading; submitBtn.style.opacity = isLoading ? 0.6 : 1; } // 触发禁用:提交开始 isLoading = true; toggleButton(); // 恢复启用:请求完成 setTimeout(() => { isLoading = false; toggleButton(); }, 2000);上述代码通过控制 `disabled` 属性阻止多次提交,`opacity` 提供视觉反馈。`toggleButton` 函数封装状态同步逻辑,确保 UI 与数据一致。getElementById或querySelector获取不存在的 DOM 节点。DOMContentLoaded后运行:document.addEventListener('DOMContentLoaded', function () { const btn = document.getElementById('submit-btn'); if (btn) { btn.addEventListener('click', handleAction); } else { console.warn('按钮元素未找到,请检查ID是否正确'); } });上述代码确保 DOM 完全加载后绑定事件,并加入空值判断提升健壮性。event.target判断触发源func NewLogger(prefix string) func(string) { return func(message string) { fmt.Println(prefix + ": " + message) } }上述代码中,NewLogger返回一个匿名函数,该函数捕获了外部变量prefix。每次调用返回的函数时,都能访问创建时所处环境中的prefix值。from functools import partial def power(base, exponent): return base ** exponent square = partial(power, exponent=2) cube = partial(power, exponent=3) print(square(5)) # 输出: 25 print(cube(5)) # 输出: 125上述代码中,`partial` 固定了 `exponent` 参数,生成新的单参数函数。`square` 和 `cube` 保留了 `power` 的逻辑,但调用更简洁。for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); } // 输出:3, 3, 3上述代码中,i使用var声明,具有函数作用域而非块级作用域。三个定时器共享同一个i,最终都输出循环结束后的值3。| 方式 | 关键词 | 输出结果 |
|---|---|---|
| 使用 var | 函数作用域 | 3, 3, 3 |
| 使用 let | 块级作用域 | 0, 1, 2 |
let,每次迭代都会创建新的绑定,确保每个闭包捕获独立的变量实例,从而避免作用域污染。document.querySelectorAll('.btn').forEach(btn => { btn.addEventListener('click', function() { // 移除所有按钮的 active 状态 document.querySelectorAll('.btn').forEach(b => b.classList.remove('active')); // 当前按钮添加 active 状态 this.classList.add('active'); }); });上述代码通过遍历按钮集合绑定点击事件。当某个按钮被点击时,首先清除所有按钮的active类,再为当前按钮添加该类,确保视觉与状态同步。ref和reactive创建响应式数据:const count = ref(0); count.value++; // 视图自动更新上述代码中,ref包装基础类型值,使其具备响应性。一旦value被修改,依赖该值的 DOM 元素将被框架调度更新。| 框架 | 响应式原理 | 更新粒度 |
|---|---|---|
| Vue | 依赖收集 + 发布订阅 | 组件级/细粒度 |
| React | 状态驱动重新渲染 | 组件级 |
在Go语言中,time.Timer可用于实现单次延时任务。调用time.NewTimer()创建定时器,通过通道接收超时信号。
timer := time.NewTimer(2 * time.Second) <-timer.C fmt.Println("2秒后执行")上述代码创建一个2秒后触发的定时器,C是其事件通道,阻塞等待直到时间到达。
对于重复性操作,time.Ticker更为合适,它会按指定间隔持续发送信号。
ticker := time.NewTicker(1 * time.Second) go func() { for range ticker.C { fmt.Println("每秒执行一次") } }() // 停止 ticker defer ticker.Stop()Ticker适用于心跳检测、状态轮询等场景,使用Stop()避免资源泄漏。
const [formData, setFormData] = useState({ name: '', email: '' }); const handleChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); };上述代码通过解构事件对象,动态更新对应字段,保证数据一致性。function useFetch(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then(res => res.json()) .then(setData); }, [url]); return data; }该自定义 Hook 可在多个组件中复用,统一处理数据获取流程。const eventBus = { events: {}, on(event, callback) { if (!this.events[event]) this.events[event] = []; this.events[event].push(callback); }, emit(event, data) { if (this.events[event]) { this.events[event].forEach(cb => cb(data)); } } };| 指标 | 重构前 | 重构后 |
|---|---|---|
| 平均加载时间 | 1.8s | 0.6s |
| 错误率 | 12% | 3% |