微信小程序封装组件自定义form内组件
最近工作写了很久没有碰过的 微信原生小程序
开发一些业务的时候难免需要对一些原生的form组件进行二次封装~
这里我封装的一个 check-group
多选的组件作为demo,能理清楚大部份组件封装的数据流思路了!
基础实现
components/multPicker/multPicker.wxml
<!--components/multPicker/multPicker.wxml-->
<view class="mult-picker">
<!-- label 区域 -->
<view class="label">默认Label</view>
<!-- placeholder 区域 value 值为空 显示 place holder-->
<view class="placeholder" wx:if="value.length>0">
<view>请选择:</view>
</view>
<view class="value" wx:else>{{value.length}}</view>
<!-- 原生的check group 绑定name -->
<checkbox-group bindchange="onChange" name="{{name}}">
<checkbox wx:for="{{options}}" wx:key="{{options[index][config.value]}}" value="{{options[index][config.value]}}">
<text>{{options[index][config.label]}}</text>
</checkbox>
</checkbox-group>
</view>
components/multPicker/multPicker.js
// components/multPicker/multPicker.js
Component({
/**
* 组件的属性列表
*/
properties: {
// 用于外部指定form表单的name
name: {
type: String,
value: ""
},
// 外部传入 value 值 可以用来回显
value: {
type: Array,
value: []
},
// 传入选择的数据数组
options: {
type: Array,
value: []
},
// 一些配置项目,指定option数据源的label字段和value字段
config: {
type: Object,
value: {
label: "title",
value: "id"
}
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
onChange(e) {
this.triggerEvent("change", e.detail.value)
}
}
})
自定义组件编程让form受控的组件
我们自定义form的某些组件,其实也希望和form事件联动,单纯靠上面的实现,定义name props从外面传入name名称绑定到自定义组件内部的checkbox上,当触发外部form submit事件 name 仍然是非受控的! (注意上面的源码是绑定了外部传入的name的喔!)

可以看到form的submit并未将我们的自定义组件控制住~🤣 因为小程序的form受控不能跨页面控制!其实官方也给出了解决方案!- 使用内置 behaviors
使自定义组件有类似于表单控件的行为。 form 组件可以识别这些自定义组件,并在 submit 事件中返回组件的字段名及其对应字段值。这将为它添加以下两个属性。
属性名 | 类型 | 描述 | 最低版本 |
---|---|---|---|
name | String | 在表单中的字段名 | 1.6.7 |
value | 任意 | 在表单中的字段值 | 1.6.7 |
对于 form 组件,目前可以自动识别下列内置 behaviors:
- wx://form-field
- wx://form-field-group
- wx://form-field-button
然后我们给我们的组件添加上!

可以看到哈!此时我们自定义的这个mult-picker
已经变成了受控组件!
解决组件数据回显
因为小程序check box的特性~当check属性为true or false 的时候,界面上才会切换是否选中~
其实很简单:
从外部使用,当拿到需要回显的值,通过自定义的value来传给我们自定义的组件~

然后组件内部接受到后~ 就可以根据 options 和 每个循环出来的checkbox的value进行对比,看看是不是包括在value中!来选择是否勾选!
这里我们需要定义一个函数来进行处理判断~
利用了小程序 WXS 的特性~
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
WXS(WeiXin Script)是内联在 WXML 中的脚本段。通过 WXS 可以在模版中内联少量处理脚本,丰富模板的数据预处理能力。
使得我们可以在页面中调用函数~
// value 就是外部传入的值,需要从页面传入进来,val是每一个checkbox绑定的值~
var isChecked = function (value, val) {
return value.indexOf(val) > -1
}
module.exports = {
isChecked: isChecked
}
组件中使用wxs
<!--components/multPicker/multPicker.wxml-->
<!-- 引入当前组件的工具脚本 -->
<wxs src="./muitPicker.wxs" module="utils">
</wxs>
<view class="mult-picker">
<!-- label 区域 -->
<view class="label">默认Label</view>
{{value}}
<!-- placeholder 区域 value 值为空 显示 place holder-->
<view class="placeholder" wx:if="value.length>0">
<view>请选择:</view>
</view>
<view class="value" wx:else>{{value.length}}</view>
<!-- 原生的check group 绑定name -->
<checkbox-group bindchange="onChange" name="{{name}}">
<!-- utils.isChecked 根据外部传入的value,和当前checkbox绑定的 value 来确定是否有被选中 -->
<checkbox checked="{{utils.isChecked(value,options[index][config.value])}}" wx:for="{{options}}" wx:key="index" value="{{options[index][config.value]}}">
<text>{{options[index][config.label]}}</text>
</checkbox>
</checkbox-group>
</view>
那么回显的问题也解决了,整个组件就是可用的状态了!
评论区