微信小程序组件间通信与传值的全面解析

embedded/2025/2/20 18:36:21/

小程序>微信小程序组件间通信与传值的全面解析

小程序>微信小程序中,组件之间的传值主要通过以下几种方式实现,每种方式都有其适用的场景和数据类型:

1. 父组件向子组件传值(父传子)

父组件可以通过 properties 将数据传递给子组件。子组件在 properties 中定义接收的属性及其类型。

子组件创建方式(以下通用)

子组件的创建方式与普通组件的创建方式有所不同,他们的最大区别就是.js文件的配置不同,以及json文件中的配置不同

  • 首先要在文件夹的根目录下创建一个components文件夹在这里插入图片描述

  • 接下来就在components文件夹中创建component文件,注意这里不是创建Page

  • components中的.js文件与之前的pages下的文件夹中的.js文件还是有差别的,各属性可以通过名字知道他是干什么的在这里插入图片描述

数据类型
  • 基本数据类型StringNumberBooleanNullUndefined
  • 复杂数据类型ObjectArrayFunction(自基础库版本 2.0.9 开始支持)。
示例代码

父组件 JSON

在父组件中要用到子组件,首先需要在父组件中的JSON文件中进行注册:

{"usingComponents": {"xbutton":"/components/xbutton/xxbutton","xbrother":"/components/xbrother/xbrother"}
}

父组件 WXML

<!-- 这里的标签child-component就是子组件的名称 -->
<!-- 属性message、list都是自定义属性。这两个属性需要在子组件的.js文件中的properties中接收,在下面会提到 --><child-component message="{{parentData}}" list="{{items}}"></child-component>

父组件 JS

Page({// 基本的定义数据data: {parentData: '来自父组件的消息',items: ['衣服', '裤子', '帽子']}
});

子组件 JS

Component({// 在父组件中定义的的两个自定义属性,在子组件中的properties选项中进行接收// 接收到父组件的值,可以当成这个组件的数据使用,在WXML文件中使用与data中的数据使用一样properties: {message: {type: String,value: '默认值'},list: {type: Array,value: []}}
});

子组件WXML

<view><!-- 接受父组件的值,在WXML中使用 --><text>父组件信息-message:{{message}}</text><view wx:for="{{list}}" wx:key="index">{{item}}</view>
</view>

2. 子组件向父组件传值(子传父)

在vue中

子组件可以通过 this.$emit 触发自定义事件,并将数据传递给父组件。父组件通过绑定事件监听器接收数据。

小程序>微信小程序

子组件可以通过 this.triggerEvent 触发自定义事件,并将数据传递给父组件。父组件通过绑定事件监听器接收数据。与vue中的方法基本相同,自定义事件的参数都相同。

数据类型
  • 任意数据类型:可以传递任意类型的数据,包括 StringNumberObjectArray 等。
示例代码

子组件 JS

Component({// methods方法区与上面的properties区、data区并列methods: {// 在子组件中定义的事件,当这个事件触发的时候,会向父组件发送一个携带有数据的方法handleClick() {// this.triggerEvent事件的两个参数,第一个是自定义事件的名字,第二个是发送的数据this.triggerEvent('customEvent', { message: '子组件传递的消息' });}}
});

子组件 WXML

<!-- bind:tap为点击事件,当点击时就会触发上面的handleClick方法就会触发了 -->
<view bind:tap="handleClick">点击我</view>

父组件 WXML

<!-- 当时在子组件中用this.triggerEvent发送的customEvent事件,就在父组件中用到。 -->
<!-- 用一个方法去接收子组件发送过来的参数 -->
<!-- 这个自定义事件是需要绑在子组件child-component上面的,注意别绑错了 -->
<child-component bind:customEvent="handleCustomEvent"></child-component>

父组件 JS

Page({// 通过子组件发送的事件,在父组件用方法handleCustomEvent(event)去触发,其中参数event就是子组件发来的数据handleCustomEvent(event) {console.log(event.detail.message); // 接收子组件传递的数据}
});

3. 兄弟组件之间的传值(子向子)

兄弟组件之间的传值没有直接的方法,需要通过上面两种传值方式的结合从而实现,下面是思路:

  • 为了方便讲述。其中一个发送数据的组件主动的一方,咱们可以把它叫做“发起者”,另一个叫做“接收者”
  • 首先,发起者把接收者想要的数据,通过子向父传值的方式,用this.triggerEvent方法自定义一个事件,把想要的数据发给,他们共同的父组件。
  • 接着,在父组件中将接收到的数据,存到data区的某个数据中。
  • 然后,运用父向子传值的方法,将data区中存的发起者发来的数据,传给接收者。
  • 最后,在接收者中的properties区去接收这个数据,在上讲到过,不会的可以再去上面仔细研究一下

思路成立,接下来进入实战:

数据类型
  • 基本数据类型StringNumberBooleanNullUndefined
  • 复杂数据类型ObjectArrayFunction(自基础库版本 2.0.9 开始支持)。
示例代码

发起者组件WXML

<button bind:tap="handleClick">点击我向父组件传值
</button>

发起者组件JS

// components/xbutton/xbutton.js
Component({properties: {},data: {},methods: {handleClick(){// 向父组件发送事件以及信息this.triggerEvent("fromChildEventName",`给兄弟组件传的值, 先交给父组件吧`)}}
})

共同的父组件WXML

<view><!-- 组件xbutton就相当于“发起者”,利用了子向父传值 --><xbutton bind:fromChildEventName="acceptMsg"></xbutton><!-- 组件xbrother就相当于“接收者”,利用了父向子传值 --><xbrother two-brother="{{childrenmsg}}"></xbrother>
</view>

共同的父组件JS

Page({data: {// 用一个数据变量准备将发起者传过来的数据存起来childrenmsg:""},acceptMsg(data){console.log("子组件传过来的数据:",data,data.detail)const childrenmsg = data.detail// 将发起者传过来的数据存起来this.setData({childrenmsg})}
})

接收者组件WXML

<view>兄弟组件通过父组件传过来的值:{{twoBrother}}</view>

接收者组件JS

// components/xbrother/xbrother.js
Component({// 接收发起者通过父组件传过来的值properties: {twoBrother:{type:String,value:""}},data: {},methods: {}
})

4. 通过 data-\* 属性传递数据

小程序>微信小程序中,data-* 属性是一种非常灵活的机制,用于在绑定事件时传递自定义数据。以下是关于 data-* 属性的详细讲解:

1. 什么是 data-\* 属性?

data-* 属性是一种自定义数据属性,允许开发者在 HTML 元素上附加任意数据。这些数据在触发事件时会被自动传递给事件处理函数,从而实现事件传参。

2. 如何使用 data-\* 属性传递数据?
2.1 在 WXML 中绑定 data-\* 属性

在 WXML 文件中,可以通过 data-* 属性将数据绑定到事件触发的元素上。* 可以是任意自定义的属性名,例如 data-iddata-name 等。

<button bindtap="handleTap" data-id="123" data-name="Tom">点击我</button>
2.2 在事件处理函数中获取数据

在事件处理函数中,可以通过 event.currentTarget.dataset 获取 data-* 属性传递的数据。

Page({handleTap(event) {console.log(event.currentTarget.dataset.id); // 输出:123console.log(event.currentTarget.dataset.name); // 输出:Tom}
});
3. 注意事项
  1. 动态绑定数据 如果需要绑定动态数据,可以使用 {{}} 语法。例如:

    HTML复制

    <button bindtap="handleTap" data-id="{{itemId}}" data-name="{{itemName}}">点击我</button>
    

    在页面的 data 中定义 itemIditemName

    Page({data: {itemId: 123,itemName: "Tom"}
    });
    
  2. 事件对象的 dataset 属性 event.currentTarget.dataset 是一个对象,包含了所有通过 data-* 传递的数据。例如:

    handleTap(event) {console.log(event.currentTarget.dataset); // { id: "123", name: "Tom" }
    }
    
  3. data-\* 属性的命名规范

    • 属性名必须以 data- 开头。
    • 属性值可以是字符串、数字或布尔值。
  4. currentTargettarget 的区别

    • event.currentTarget 指向绑定事件的元素。
    • event.target 指向触发事件的元素。
    • 在事件冒泡时,currentTargettarget 可能不同。
4. 使用场景

data-* 属性常用于以下场景:

  • 在按钮点击事件中传递额外参数。
  • 在列表渲染中为每个列表项绑定唯一标识。
  • 在自定义组件中传递数据。
5. 示例
5.1 动态绑定数据

WXML

<view wx:for="{{items}}" bindtap="handleTap" data-id="{{item.id}}" data-name="{{item.name}}">{{item.name}}
</view>

JS

Page({data: {items: [{ id: 1, name: "Item 1" },{ id: 2, name: "Item 2" }]},handleTap(event) {console.log(event.currentTarget.dataset.id); // 输出:1 或 2console.log(event.currentTarget.dataset.name); // 输出:Item 1 或 Item 2}
});
5.2 自定义组件中的使用

子组件 WXML

<button bindtap="handleTap" data-id="123">点击我</button>

子组件 JS

Component({methods: {handleTap(event) {this.triggerEvent("customEvent", event.currentTarget.dataset);}}
});

父组件 WXML

<custom-component bind:customEvent="handleCustomEvent"></custom-component>

父组件 JS

Page({handleCustomEvent(event) {console.log(event.detail.id); // 输出:123}
});

通过 data-* 属性,开发者可以在事件处理中灵活传递和获取数据,从而实现复杂的功能。

5. 直接访问子组件实例

小程序>微信小程序中,this.selectComponent 是一个非常强大的方法,用于在父组件中获取子组件的实例。通过这个实例,父组件可以直接访问子组件的内部数据、方法,甚至触发子组件的行为。以下是详细的使用方法和注意事项:

1. this.selectComponent 的基本用法

this.selectComponent 方法通过选择器(selector)来获取子组件的实例。选择器可以是类名(.class)或 ID(#id)。

语法:

const componentInstance = this.selectComponent(selector);
  • selector:用于选择子组件的选择器,可以是类名(如 .my-component)或 ID(如 #my-component)。
  • 返回值:返回一个组件实例对象,如果未找到匹配的组件,则返回 null

示例:

假设有一个子组件 child-component,其 WXML 文件如下:

<view id="child" class="child-component">子组件内容</view>

在父组件中,可以通过以下方式获取子组件实例:

Page({// 生命周期函数--监听页面加载onLoad() {const childComponent = this.selectComponent("#child");if (childComponent) {console.log(childComponent.data); // 访问子组件的 data 数据childComponent.someMethod(); // 调用子组件的方法} else {console.error("未找到子组件实例");}}
});
2. 获取子组件实例的用途

通过 this.selectComponent 获取子组件实例后,可以实现以下功能:

  1. 访问子组件的内部数据
    • 使用 componentInstance.datacomponentInstance.properties 访问子组件的内部数据。
  2. 调用子组件的方法
    • 直接通过 componentInstance.someMethod() 调用子组件中定义的方法。
  3. 动态修改子组件的数据
    • 使用 componentInstance.setData() 修改子组件的内部数据。
3. 注意事项
  1. 选择器的范围
    • this.selectComponent 的选择器范围仅限于当前页面或组件内部。 . 组件实例的返回值
    • 默认情况下,this.selectComponent 返回的是子组件的实例对象。
    • 如果需要自定义返回值,可以在子组件中使用 wx://component-export 行为。

自定义返回值示例:

在子组件中使用 wx://component-export

Component({behaviors: ['wx://component-export'],export: {myField: 'myValue'}
});

父组件获取子组件实例时,返回的是自定义的对象:

const childComponent = this.selectComponent("#child");
console.log(childComponent.myField); // 输出:myValue
  1. 跨组件通信的限制
    • 默认情况下,小程序与插件之间、不同插件之间的组件无法通过 this.selectComponent 获取实例(返回 null)。
    • 如果需要跨组件通信,需要在子组件中明确允许通过 wx://component-export
4. 使用场景
  • 动态调用子组件方法:父组件可以根据用户操作动态调用子组件的方法。
  • 访问子组件数据:父组件可以获取子组件的内部状态,用于同步或验证。
  • 组件间通信:在复杂的组件结构中,this.selectComponent 是一种高效的通信方式。

通过 this.selectComponent,开发者可以灵活地操作子组件的实例,实现复杂的组件间交互。

总结

  • 父传子:通过 properties 传递,支持基本和复杂数据类型。
  • 子传父:通过 this.triggerEvent 触发事件,支持任意数据类型。
  • 兄弟传:通过上面两种方法结合,支持基本和复杂数据类型。
  • 事件传参:通过 data-* 属性传递自定义数据,支持基本数据类型。
  • 直接访问子组件实例:通过 this.selectComponent,适用于需要直接操作子组件的场景。

这些方式共同构成了小程序>微信小程序中组件间通信的完整体系,可以根据具体需求选择合适的方式进行数据传递。


http://www.ppmy.cn/embedded/163143.html

相关文章

大学信息安全技术 期末考试复习题

一、单选题&#xff08;一&#xff09; 1、在以下人为的恶意攻击行为中&#xff0c;属于主动攻击的是&#xff08; &#xff09;A A&#xff0e;数据篡改及破坏 B&#xff0e;数据窃听 C&#xff0e;数据流分析 D&#xff0e;非法访问 2、数据完整性指的是&#xff08; &#x…

用deepseek学大模型03-数学基础 概率论 条件概率 全概率公式 贝叶斯定理

要深入浅出地理解条件概率与贝叶斯定理&#xff0c;可以从以下几个方面入手&#xff0c;结合理论知识和实例进行学习&#xff1a; 贝叶斯定理与智能世界的暗语 条件概率&#xff0c;全概率公式与贝叶斯公式的推导&#xff0c;理解和应用 拉普拉斯平滑 贝叶斯解决垃圾邮件分类 …

LVS的NAT及DR模式

DR模式&#xff1a; 原理&#xff1a;负载均衡器接收到客户的请求数据包时&#xff0c;根据调度算法决定将请求发送给哪个后端的真实服务器&#xff08;RS&#xff09;。然后负载均衡器就把客户端发送的请求数据包的目标MAC地址改成后端真实服务器的MAC地址&#xff08;R-MAC&a…

【Elasticsearch】字符过滤器Character Filters

在 Elasticsearch 中&#xff0c;字符过滤器&#xff08;Character Filters&#xff09;是文本分析器的重要组成部分&#xff0c;用于在分词之前对原始文本进行预处理。它们可以对字符流进行转换&#xff0c;例如添加、删除或更改字符。Elasticsearch 提供了三种内置的字符过滤…

数据结构——哈希表使用

目标&#xff1a;利用哈希表存放若干个单词&#xff0c;用户输入某个单词&#xff0c;查询在哈希表中是否存在该单词 主函数 main.c ↓↓↓↓↓ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "hashtable.h"int main(vo…

Spring Boot 从 2.7.x 升级到 3.3注意事项

将 Spring Boot 从 2.7.x 升级到 3.3 是一个重要的迁移过程&#xff0c;特别是因为 Spring Boot 3.x 系列基于 Jakarta EE 9&#xff0c;而不再使用 Java EE。此版本升级伴随着许多重大变化&#xff0c;以下是你在升级过程中需要注意的关键事项&#xff1a; 1. JDK 版本升级 …

Qt——连接MySQL数据库之编译数据库驱动的方法详细总结(各版本大同小异,看这一篇就够了)

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实战》 《实用硬件方案设计》 《结构建模设…

运用Deek Seeker协助数据分析

我的数据源有两张表&#xff0c;一个是每日销售表(字段有日期、产品名称、实际销量)&#xff0c;一个是每月目标表(字段有年度月份、产品名称、目标销量);我的需求是&#xff0c;按月、按年来统计每个产品的目标完成情况请问用PowerBl进行分析&#xff0c;应该如何建立数据模型…