微信小程序,通过事件传递数据

小程序事件机制实践
本文介绍了一种在小程序中实现组件间数据传递的方法,通过自定义的订阅发布模式,解决了组件间通信难题,并提供了代码实现及注意事项。

在做小程序的时候,发现在没有使用第三方库的时候,组件间有数据传递是很麻烦的事情,最后自己写了个数据传递的方法,这里用的是订阅发布模式,也就是我们说的事件。

有什么不足希望大家可以指出,大家可以一起相互学习一下!

话不多说,直接上代码:

// 用来保存所有绑定的事件
const events = {};

// 监听事件
function on(name, self, callback) {
    // self用来保存小程序page的this,方便调用this.setData()修改数据
  const tuple = [self, callback];
  const callbacks = events[name];
  let isCallback = null;
  // 判断事件库里面是否有对应的事件
  if (Array.isArray(callbacks)) {
      // 相同的事件不要重复绑定
    const selfCallbacks = callbacks.filter(item => {
      return self === item[0];
    });
    if (selfCallbacks.length === 0) {
      callbacks.push(tuple);
    } else {
      for(const item of selfCallbacks){
        if(callback.toString() !== item.toString()){
          isCallback = true;
        }
      }
      !isCallback && selfCallbacks[0].push(callback);
    }
  } else {
     // 事件库没有对应数据,就将事件存进去
    events[name] = [tuple];
  }
}

// 移除监听的事件
function remove(name, self) {
  const callbacks = events[name];
  if (Array.isArray(callbacks)) {
    events[name] = callbacks.filter(tuple => {
      return tuple[0] !== self;
    });
  }
}

// 触发监听事件
function emit(name, data = {}) {
  const callbacks = events[name];
  if (Array.isArray(callbacks)) {
    callbacks.map(tuple => {
      const self = tuple[0];
      for (const callback of tuple) {
        console.log( typeof callback);
        if (typeof callback === 'function') {
          // 用call绑定函数调用的this,将数据传递过去
          callback.call(self, deepClone(data));
        }
      }
    });
  }
}

export {
  on,
  remove,
  emit
};

这里数据我用了深克隆,主要是为了防止传递的数据是引用类型时,造成的数据污染。深克隆我就不多说了,不懂得自行百度。

// 深克隆
function deepClone(obj) {
  if (typeof obj !== 'object') {
    return obj;
  } else {
    const newObj = obj.constructor === Array ? [] : {};

    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (obj[key] && typeof obj[key] === 'object') {
          newObj[key] = deepClone(obj[key]);
        } else {
          newObj[key] = obj[key];
        }
      }
    }
    return newObj;
  }
}

现在我们就可以on 监听事件, emit去触发事件了,不过记得卸载page时,一定要将监听的事件remove掉,避免内存泄露。

### 如何在微信小程序中通过点击事件传递数据微信小程序开发过程中,可以通过多种方式实现点击事件的数据传递。以下是常见的方法及其具体实现: #### 方法一:`data-*` 属性传参 利用 HTML 中的 `data-*` 自定义属性,在绑定事件时将参数附加到标签上。当触发事件时,可以在回调函数中通过 `event.detail` 或者 `event.currentTarget.dataset` 获取对应的参数。 ```html <!-- WXML --> <button data-id="123" bindtap="handleClick">点击我</button> ``` ```javascript // JS 文件 Page({ handleClick(event) { const id = event.currentTarget.dataset.id; // 获取自定义属性中的值 console.log('按钮被点击,id:', id); } }); ``` 上述代码展示了如何通过 `data-*` 属性来传递简单的字符串或者数值类型的参数[^2]。 #### 方法二:使用对象作为上下文传参 除了通过 `data-*` 方式外,还可以直接在绑定事件时传递复杂对象作为上下文的一部分。这种方式适用于需要传递多个字段的情况。 ```html <!-- WXML --> <view wx:for="{{items}}" wx:key="index"> <button bindtap="handleItemClick" data-item="{{item}}">{{item.name}}</button> </view> ``` ```javascript // JS 文件 Page({ data: { items: [ { name: '苹果', price: 5 }, { name: '香蕉', price: 3 } ] }, handleItemClick(event) { const item = event.currentTarget.dataset.item; console.log('选中的商品:', item); // 输出完整的对象 } }); ``` 此示例说明了如何在一个列表渲染场景下,通过 `bindtap` 绑定事件并传递整个对象给处理函数。 #### 方法三:父组件向子组件传递数据并通过事件返回 如果涉及到父子组件间的交互,则需先由父组件向子组件发送初始数据,再由子组件通过事件机制反馈修改后的状态回父级。 ##### 子组件 (child.wxml 和 child.js) ```html <!-- child.wxml --> <button bindtap="onChildClick">通知父组件</button> ``` ```javascript // child.js Component({ properties: { messageFromParent: String, // 接收来自父组件的消息 }, methods: { onChildClick() { this.triggerEvent('customEvent', { detailMessage: '这是子组件发来的消息' }); } } }); ``` ##### 父组件 (parent.wxml 和 parent.js) ```html <!-- parent.wxml --> <child-component message-from-parent="你好子组件!" bindcustomEvent="receiveMessage"></child-component> ``` ```javascript // parent.js Page({ receiveMessage(e) { console.log('收到子组件的信息:', e.detail.detailMessage); } }); ``` 这里演示了一个典型的父子组件通信模式,其中包含了从父到子以及反方向的数据流动过程[^3]。 --- ### 总结 综上所述,微信小程序提供了灵活多样的途径用于解决不同场景下的点击事件数据传输需求。无论是基础页面内的简单操作还是复杂的跨组件协作都可以找到合适的解决方案。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值