微信小程序页面事件

175 阅读4分钟

一、前言

在微信小程序开发中,页面事件 是控制页面行为、响应用户操作和实现页面间通信的重要手段。无论是页面加载时的数据请求、页面显示时的状态更新,还是按钮点击、滚动事件的监听,都离不开事件机制的支持。

本文将带你全面了解小程序中的页面事件体系,包括:

✅ 小程序页面的生命周期事件
✅ 页面间通信方式与事件传参
✅ 用户交互事件的绑定与处理
✅ 自定义事件的创建与触发
✅ 实际开发中的常见问题与优化建议

并通过完整的代码示例帮助你快速上手并熟练使用小程序事件机制。

二、页面生命周期事件

页面生命周期事件是指小程序框架自动调用的方法,用于通知页面当前所处的状态。这些事件在 Page() 对象中声明。

常见生命周期事件如下:

方法描述
onLoad(options)页面加载时触发,可获取跳转参数
onShow()页面显示时触发,如从后台切换回前台
onReady()页面初次渲染完成时触发(只执行一次)
onHide()页面隐藏时触发,如跳转到其他页面或进入后台
onUnload()页面卸载时触发,如使用 navigateBack 返回

✅ 示例:页面生命周期事件演示

Page({
  onLoad(options) {
    console.log('页面加载', options);
    // 初始化数据
  },

  onShow() {
    console.log('页面显示');
    // 可用于刷新数据
  },

  onReady() {
    console.log('页面初次渲染完成');
    // 可在此初始化动画或组件
  },

  onHide() {
    console.log('页面隐藏');
    // 暂停播放音乐、停止计时器等
  },

  onUnload() {
    console.log('页面卸载');
    // 清除定时器、释放资源
  }
});

三、页面间通信与事件传参

页面之间可以通过跳转携带参数,也可以通过全局变量、本地存储等方式进行通信。

✅ 方式一:URL 查询 参数传参(推荐)

发送端:

wx.navigateTo({
  url: '/pages/details/details?id=123&name=张三'
});

接收端(details.js):

Page({
  onLoad(options) {
    console.log(options.id);   // 输出 123
    console.log(options.name); // 输出 张三
  }
});

✅ 方式二:全局变量传参(适用于少量共享数据)

app.js:

App({
  globalData: {}
});

页面 A 设置值:

const app = getApp();
app.globalData.userInfo = { name: 'Tom' };

页面 B 获取值:

const app = getApp();
console.log(app.globalData.userInfo); // 输出 { name: 'Tom' }

✅ 方式三:本地缓存传参(适合持久化数据)

// 页面 A 存储数据
wx.setStorageSync('token', 'abc123');

// 页面 B 获取数据
const token = wx.getStorageSync('token');
console.log(token); // 输出 abc123

四、用户交互事件绑定与处理

✅ WXML 中绑定事件(以点击为例)

<button bindtap="onClick">点击我</button>
<input bindinput="onInput" placeholder="请输入内容" />
<view catchtouchstart="onTouchStart">触摸开始</view>

✅ JS 中定义事件处理函数

Page({
  onClick(e) {
    console.log('按钮被点击了');
  },

  onInput(e) {
    const value = e.detail.value;
    console.log('输入内容:', value);
  },

  onTouchStart(e) {
    console.log('触摸开始位置:', e.touches[0]);
  }
});

五、自定义事件(事件总线 / 全局事件)

虽然小程序不直接支持 DOM 事件模型,但我们可以通过自定义“事件中心”来模拟类似功能。

✅ 实现一个简单的事件中心(utils/eventBus.js)

class EventBus {
  constructor() {
    this.handlers = {};
  }

  on(eventName, handler) {
    if (!this.handlers[eventName]) {
      this.handlers[eventName] = [];
    }
    this.handlers[eventName].push(handler);
  }

  emit(eventName, data) {
    const handlers = this.handlers[eventName];
    if (handlers && handlers.length > 0) {
      handlers.forEach(handler => handler(data));
    }
  }

  off(eventName, handler) {
    const handlers = this.handlers[eventName];
    if (handlers) {
      this.handlers[eventName] = handlers.filter(h => h !== handler);
    }
  }
}

export default new EventBus();

✅ 使用示例:

页面 A 触发事件:

import eventBus from '../../utils/eventBus';

eventBus.emit('updateData', { newData: 'Hello World' });

页面 B 监听事件:

import eventBus from '../../utils/eventBus';

Page({
  onLoad() {
    eventBus.on('updateData', (data) => {
      console.log('收到事件数据:', data); // 输出 { newData: 'Hello World' }
    });
  }
});

六、实际开发建议与最佳实践

场景建议
页面初始化✅ 在 onLoad 中请求数据
数据刷新✅ 在 onShow 中重新加载或更新状态
资源清理✅ 在 onUnload 中清除定时器、取消监听器
表单验证✅ 在 bindinput 或 bindsubmit 中处理输入逻辑
多页面通信✅ 使用全局变量 + 事件中心机制
用户体验优化✅ 在交互事件中添加 Loading 提示、防抖节流处理

七、常见问题与解决方法

问题原因解决方案
页面参数未接收到未在 onLoad 中处理检查是否正确接收 options
输入框无法输入绑定错误或未赋值检查 value 和 bindinput 是否同步
事件未触发函数名拼写错误或未绑定检查 WXML 中事件绑定是否正确
页面栈混乱多次跳转未关闭控制跳转深度,避免超过 10 层
事件重复监听多次注册未解绑在 onUnload 中使用 off() 解除绑定
数据不同步未监听页面显示事件在 onShow 中更新 UI 数据

八、总结对比表:常用页面事件一览

事件触发时机是否可多次触发
onLoad页面加载❌(仅一次)
onShow页面显示
onReady页面初次渲染完成❌(仅一次)
onHide页面隐藏
onUnload页面卸载❌(仅一次)
bindtap模拟点击
bindinput输入变化
bindchange选择器/开关变化

九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!