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

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

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

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

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

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

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

  • 首先要在文件夹的根目录下创建一个components文件夹

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

  • components中的.js文件与之前的pages下的文件夹中的.js文件还是有差别的,各属性可以通过名字知道他是干什么的

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

父组件 JSON

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

json 复制代码
{
  "usingComponents": {
    "xbutton":"/components/xbutton/xxbutton",
    "xbrother":"/components/xbrother/xbrother"
  }
}

父组件 WXML

html 复制代码
<!-- 这里的标签child-component就是子组件的名称 -->
<!-- 属性message、list都是自定义属性。这两个属性需要在子组件的.js文件中的properties中接收,在下面会提到 -->

<child-component message="{{parentData}}" list="{{items}}"></child-component>

父组件 JS

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

子组件 JS

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

子组件WXML

vue 复制代码
<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

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

子组件 WXML

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

父组件 WXML

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

父组件 JS

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

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

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

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

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

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

发起者组件WXML

vue 复制代码
<button bind:tap="handleClick">
    点击我向父组件传值
</button>

发起者组件JS

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

共同的父组件WXML

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

共同的父组件JS

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

接收者组件WXML

vue 复制代码
<view>兄弟组件通过父组件传过来的值:{{twoBrother}}</view>

接收者组件JS

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 等。

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

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

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

    HTML复制

    html 复制代码
    <button bindtap="handleTap" data-id="{{itemId}}" data-name="{{itemName}}">点击我</button>

    在页面的 data 中定义 itemIditemName

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

    javascript 复制代码
    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

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

JS

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

子组件 WXML

html 复制代码
<button bindtap="handleTap" data-id="123">点击我</button>

子组件 JS

javascript 复制代码
Component({
  methods: {
    handleTap(event) {
      this.triggerEvent("customEvent", event.currentTarget.dataset);
    }
  }
});

父组件 WXML

html 复制代码
<custom-component bind:customEvent="handleCustomEvent"></custom-component>

父组件 JS

javascript 复制代码
Page({
  handleCustomEvent(event) {
    console.log(event.detail.id); // 输出:123
  }
});

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

5. 直接访问子组件实例

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

1. this.selectComponent 的基本用法

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

语法:

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

示例:

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

html 复制代码
<view id="child" class="child-component">子组件内容</view>

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

javascript 复制代码
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

javascript 复制代码
Component({
  behaviors: ['wx://component-export'],
  export: {
    myField: 'myValue'
  }
});

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

javascript 复制代码
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,适用于需要直接操作子组件的场景。

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

相关推荐
luckyext3 小时前
HBuilderX中,VUE生成随机数字,vue调用随机数函数
前端·javascript·vue.js·微信小程序·小程序
毕业设计-015 小时前
0081.基于springboot+uni-app的垃圾分类小程序+论文
spring boot·小程序·uni-app
狂团商城小师妹7 小时前
挪车小程序挪车二维码php+uniapp
微信小程序·小程序·uni-app·微信公众平台
V+zmm101347 小时前
基于微信小程序的家政服务预约系统的设计与实现(php论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计
社会底层无业大学生8 小时前
uniapp微信小程序PC端选择文件(无法使用wx.chooseMessageFile问题)
微信小程序·小程序·uni-app
这里是杨杨吖9 小时前
SpringBoot+uniApp日历备忘录小程序系统 附带详细运行指导视频
spring boot·小程序·uni-app·日历备忘录
寰宇软件9 小时前
PHP培训机构教务管理系统小程序源码
小程序·uni-app·vue·php
Stanford_11069 小时前
C++中常用的十大排序方法之3——插入排序
c++·算法·微信小程序·排序算法·微信公众平台·twitter·微信开放平台
『 时光荏苒 』12 小时前
hbuilderx 小程序分包_微信小程序关于分包【收藏版】
微信小程序·小程序
V+zmm1013412 小时前
基于微信小程序的民宿短租系统设计与实现(ssm论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计