关键在于“页面传入组件的 props 和组件内部的属性绑定是怎么连接的”
🔍 一、组件与页面属性传递机制
我们从这段页面调用开始:
✅ 页面调用组件:
<common-filter
label="{{item.label}}"
options="{{item.options}}"
value="{{item.value}}"
data-key="{{item.key}}"
bind:change="onFilterChange"
/>
意思是:把 item.label
的值传给组件的 label
属性,把 item.options
的值传给组件的 options
属性……以此类推。
✅ 组件定义:
组件内部用的是这些 properties
:
properties: {
label: String,
options: Array,
value: Number
}
你还用了:
<picker
mode="selector"
value="{{value}}"
range="{{options}}"
>
...
<text class="value-text">{{options[value]}}</text>
</picker>
🔗 对应关系图:
页面传入属性 | 组件接收属性 | 组件 WXML 使用方式 |
---|---|---|
label="{{item.label}}" | label: String | {{label}} (没显示但可输出) |
options="{{item.options}}" | options: Array | range="{{options}}" 、{{options[value]}} |
value="{{item.value}}" | value: Number | value="{{value}}" |
✅ 所以你说的问题是:
为什么我一开始写
range="{{item.options}}"
就显示不出来,必须写options="{{item.options}}"
?
❗答案是:range="{{item.options}}"
是错误的写法,它会把 item.options
直接作为 picker
的属性绑定,而不是传给组件。
你页面里用 wx:for
是在一个页面的 <block>
中遍历变量 item
,但 item.options
是页面中的变量,不能直接作为组件内 picker
的 range
使用。
正确做法是:
- 在页面
<common-filter ... options="{{item.options}}" />
把值传给组件 - 在组件里使用
range="{{options}}"
来读取你传进来的options
值
这就是正确的 **“页面→组件属性传值→组件内部使用”**的链条。
✅ 总结
错误用法(你之前尝试) | 问题 |
---|---|
range="{{item.options}}" | 组件内部无法识别页面的 item ,绑定失败 |
正确做法 | 解释 |
---|---|
options="{{item.options}}" | 将 item.options 传入组件的 options 属性,组件内部再使用 {{options}} 来访问 |
下面是一个清晰的 「小程序父页面向子组件传值的图解」,帮你直观理解 label
/ options
/ value
等属性是怎么从页面传入组件并被使用的。
🧩 图解:页面传值到组件内部的完整路径
【页面 Page】 【组件 Component】
┌────────────────────┐ ┌────────────────────────────┐
│ wx:for="filterConfigs" 迭代 item │ │ properties: { │
│ │ │ label: String, │
│ <common-filter │──label─────▶│ options: Array, │
│ label="{{item.label}}" │──options────▶│ value: Number │
│ options="{{item.options}}" │──value──────▶│ } │
│ value="{{item.value}}" │ └────────────────────────────┘
│ /> │
└────────────────────┘
▼
【组件内部 WXML 使用 props】
┌────────────────────────────┐
│ <picker │
│ mode="selector" │
│ value="{{value}}" │ ◀─────── 来自页面传入的 value
│ range="{{options}}" │ ◀─────── 来自页面传入的 options
│ > │
│ <view> │
│ {{options[value]}} │ ◀────── 使用 value 作为下标显示当前选中内容
│ </view> │
│ </picker> │
└────────────────────────────┘
✅ 示例回顾(实际数据传输)
假设你在页面有这样一个配置项:
data: {
filterConfigs: [
{
key: 'periodType',
label: '报告类型',
options: ['线上周', '线下周', '线上月', '线下月'],
value: 0
}
]
}
页面中调用组件时:
<common-filter
label="{{item.label}}"
options="{{item.options}}"
value="{{item.value}}"
/>
组件中定义:
Component({
properties: {
label: String,
options: Array,
value: Number
}
})
组件中使用:
<picker range="{{options}}" value="{{value}}">
{{options[value]}}
</picker>
📌 总结
步骤 | 说明 |
---|---|
页面定义数据 | filterConfigs 列表包含 label、options、value 等 |
页面向组件传值 | 使用 label="{{item.label}}" 等方式传入 |
组件声明接收属性 | 在 properties 中写明对应字段 |
组件内部使用 | 用 {{label}} 、{{options}} 、{{options[value]}} 等取值 |
✅ 总结
页面传值写法 | 组件中 properties 定义 | 是否生效 |
---|---|---|
value="{{item.value}}" | value: Number | ✅ 是 |
myValue="{{item.value}}" | myValue: Number | ✅ 是 |
myValue="{{item.value}}" | value: Number | ❌ 否 |
只要 左右字段名对得上,字段值是什么都无所谓,系统只看你传给组件的是哪个“键”。