4、基础组件:视图容器、基础内容与表单组件
好,咱们今天聊聊小程序里最常用的一批基础组件。说实话,这些组件看着简单,但跨平台时坑不少。我这些年踩过的雷,今天一次性给你说清楚。
4.1 视图容器:view / scroll-view / swiper
这三个组件,说白了就是页面的骨架。没有它们,你的内容就没地方放。
4.1.1 view —— 最基础的块级容器
view 相当于 HTML 里的 div。但有个区别:小程序里 view 默认是 display: block,而且不支持 flex 以外的复杂布局?嗯,其实支持,但各平台表现不一致。
核心要点:在微信、支付宝、抖音等平台,view 的 hover-class 属性表现不同。微信支持点击态,支付宝需要额外配置。
<!-- 微信端正常,支付宝端需要加 hover-stop-propagation -->
<view class="card" hover-class="card-hover">
点击我试试
</view>
我在项目中遇到过一个问题:同样的代码,在微信上点击有反馈,在支付宝上死活没反应。后来发现是支付宝要求 hover-start-time 和 hover-stay-time 必须显式设置。你想想看,这种细节文档里其实有,但谁会一条条去对?
4.1.2 scroll-view —— 可滚动区域
这个组件我建议你谨慎使用。为什么?因为各平台对 scroll-view 的 scroll-into-view 和 scroll-anchoring 支持程度不一样。
避坑指南:我曾经在抖音小程序里用 scroll-view 做长列表,结果在 iOS 上滚动卡顿严重。后来发现是 enhanced 属性没开。微信默认开启,抖音需要手动设置。
<!-- 推荐写法:兼容主流平台 -->
<scroll-view
scroll-y
enhanced="{{true}}"
show-scrollbar="{{false}}"
bindscrolltolower="loadMore">
<view wx:for="{{list}}">{{item.name}}</view>
</scroll-view>
我个人习惯:如果只是简单滚动,直接用 view 加 overflow: scroll 更省心。只有需要监听滚动事件或锚点定位时,才用 scroll-view。
4.1.3 swiper —— 轮播图组件
轮播图是每个 App 的标配。swiper 组件在微信里表现最好,但在其他平台要注意:
| 属性 | 微信 | 支付宝 | 抖音 |
|---|---|---|---|
| autoplay | ✅ 正常 | ✅ 正常 | ⚠️ 需设置 interval |
| circular | ✅ 支持 | ✅ 支持 | ⚠️ 部分版本有 bug |
| indicator-dots | ✅ 自定义方便 | ✅ 样式有限 | ⚠️ 需用 slot 自定义 |
小技巧:如果你需要自定义指示器样式,建议用 swiper 的 slot 功能,而不是依赖默认的 indicator-dots。这样跨平台表现更一致。
4.2 基础内容:text / icon / progress
这些组件负责展示文字、图标和进度。看着简单,但跨平台时字体渲染和图标库的差异会让你头疼。
4.2.1 text —— 文本组件
text 是唯一一个可以选中内容的组件。微信里支持 selectable 属性,支付宝也支持,但抖音不支持长按选中。
<!-- 微信和支付宝可以选中,抖音不行 -->
<text selectable="{{true}}">这段文字可以复制</text>
我记得有一次,用户反馈在抖音上无法复制订单号。查了半天,发现是 text 的 selectable 在抖音上根本没实现。最后只能用 rich-text 加 clipboard API 曲线救国。
4.2.2 icon —— 图标组件
各平台内置的图标库完全不同。微信有 success、info 等,支付宝有 check、close,抖音的图标更少。
建议:不要依赖平台内置图标。用自定义图标(比如 iconfont)或者 SVG 图片,跨平台表现更稳定。
<!-- 不推荐:各平台图标名不同 -->
<icon type="success" size="20" />
<!-- 推荐:使用自定义图标 -->
<image src="/images/icon-success.png" style="width:20px;height:20px;" />
4.2.3 progress —— 进度条
这个组件相对简单。但要注意:微信的 progress 支持 activeColor 和 backgroundColor,支付宝的 progress 属性名略有不同。
| 属性 | 微信 | 支付宝 |
|---|---|---|
| percent | 0-100 | 0-100 |
| stroke-width | ✅ | ✅ |
| activeColor | ✅ | ⚠️ 用 color 代替 |
注意:在支付宝小程序里,progress 的 active 动画效果默认关闭,需要手动设置 animation="{{true}}"。
4.3 表单组件:button / input / checkbox
表单是用户交互的核心。跨平台时,表单组件的差异最大,尤其是 button 的开放能力。
4.3.1 button —— 按钮组件
button 在微信里功能最强大,支持 open-type 获取用户信息、手机号等。但在支付宝和抖音里,open-type 的值完全不同。
<!-- 微信:获取用户信息 -->
<button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">
获取用户信息
</button>
<!-- 支付宝:使用 my.getAuthCode -->
<button onTap="getAuthCode">
获取用户信息
</button>
我个人习惯:封装一个 auth-button 组件,内部判断平台,调用不同的 API。这样业务代码里只用写 <auth-button>登录</auth-button>,省心很多。
4.3.2 input —— 输入框
input 的坑主要在键盘类型和事件上。微信支持 type="nickname",支付宝不支持。还有 confirm-type 属性,各平台支持程度不同。
经验之谈:如果你需要数字键盘,微信用 type="number",支付宝用 type="digit"。别问我怎么知道的,都是血泪教训。
<!-- 微信 -->
<input type="number" placeholder="请输入数字" />
<!-- 支付宝 -->
<input type="digit" placeholder="请输入数字" />
4.3.3 checkbox —— 复选框
checkbox 相对简单,但要注意 checkbox-group 的 bindchange 事件返回值格式。微信返回 detail.value 是数组,支付宝也是数组,但抖音可能返回字符串。
| 平台 | bindchange 返回值 |
|---|---|
| 微信 | { detail: { value: ['a', 'b'] } } |
| 支付宝 | { detail: { value: ['a', 'b'] } } |
| 抖音 | { detail: { value: 'a,b' } }(字符串) |
避坑指南:我曾经在抖音上做多选功能,直接用 value.includes('a') 判断,结果因为返回值是字符串,includes 方法直接报错。后来统一用 String(value).split(',') 处理,才解决问题。
小结
基础组件虽然简单,但跨平台时细节差异很多。我的建议是:
- 视图容器:优先用
view,少用scroll-view,swiper的自定义指示器要提前测试 - 基础内容:
text注意选中功能,icon用自定义图标,progress属性名要适配 - 表单组件:
button的开放能力差异最大,input的键盘类型要区分,checkbox的返回值格式要统一处理
嗯,这些经验都是真金白银换来的。你写代码时多留个心眼,遇到奇怪的问题,先怀疑是不是平台差异。下一章咱们聊列表渲染和条件渲染,那个坑更多,到时候再细说。