4、基础组件:视图容器、基础内容与表单组件

好,咱们今天聊聊小程序里最常用的一批基础组件。说实话,这些组件看着简单,但跨平台时坑不少。我这些年踩过的雷,今天一次性给你说清楚。

4.1 视图容器:view / scroll-view / swiper

这三个组件,说白了就是页面的骨架。没有它们,你的内容就没地方放。

4.1.1 view —— 最基础的块级容器

view 相当于 HTML 里的 div。但有个区别:小程序里 view 默认是 display: block,而且不支持 flex 以外的复杂布局?嗯,其实支持,但各平台表现不一致。

核心要点:在微信、支付宝、抖音等平台,viewhover-class 属性表现不同。微信支持点击态,支付宝需要额外配置。

<!-- 微信端正常,支付宝端需要加 hover-stop-propagation -->
<view class="card" hover-class="card-hover">
  点击我试试
</view>

我在项目中遇到过一个问题:同样的代码,在微信上点击有反馈,在支付宝上死活没反应。后来发现是支付宝要求 hover-start-timehover-stay-time 必须显式设置。你想想看,这种细节文档里其实有,但谁会一条条去对?

4.1.2 scroll-view —— 可滚动区域

这个组件我建议你谨慎使用。为什么?因为各平台对 scroll-viewscroll-into-viewscroll-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>

我个人习惯:如果只是简单滚动,直接用 viewoverflow: scroll 更省心。只有需要监听滚动事件或锚点定位时,才用 scroll-view

4.1.3 swiper —— 轮播图组件

轮播图是每个 App 的标配。swiper 组件在微信里表现最好,但在其他平台要注意:

属性 微信 支付宝 抖音
autoplay ✅ 正常 ✅ 正常 ⚠️ 需设置 interval
circular ✅ 支持 ✅ 支持 ⚠️ 部分版本有 bug
indicator-dots ✅ 自定义方便 ✅ 样式有限 ⚠️ 需用 slot 自定义

小技巧:如果你需要自定义指示器样式,建议用 swiperslot 功能,而不是依赖默认的 indicator-dots。这样跨平台表现更一致。

4.2 基础内容:text / icon / progress

这些组件负责展示文字、图标和进度。看着简单,但跨平台时字体渲染和图标库的差异会让你头疼。

4.2.1 text —— 文本组件

text 是唯一一个可以选中内容的组件。微信里支持 selectable 属性,支付宝也支持,但抖音不支持长按选中。

<!-- 微信和支付宝可以选中,抖音不行 -->
<text selectable="{{true}}">这段文字可以复制</text>

我记得有一次,用户反馈在抖音上无法复制订单号。查了半天,发现是 textselectable 在抖音上根本没实现。最后只能用 rich-textclipboard API 曲线救国。

4.2.2 icon —— 图标组件

各平台内置的图标库完全不同。微信有 successinfo 等,支付宝有 checkclose,抖音的图标更少。

建议:不要依赖平台内置图标。用自定义图标(比如 iconfont)或者 SVG 图片,跨平台表现更稳定。

<!-- 不推荐:各平台图标名不同 -->
<icon type="success" size="20" />

<!-- 推荐:使用自定义图标 -->
<image src="/images/icon-success.png" style="width:20px;height:20px;" />

4.2.3 progress —— 进度条

这个组件相对简单。但要注意:微信的 progress 支持 activeColorbackgroundColor,支付宝的 progress 属性名略有不同。

属性 微信 支付宝
percent 0-100 0-100
stroke-width
activeColor ⚠️ 用 color 代替

注意:在支付宝小程序里,progressactive 动画效果默认关闭,需要手动设置 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-groupbindchange 事件返回值格式。微信返回 detail.value 是数组,支付宝也是数组,但抖音可能返回字符串。

平台 bindchange 返回值
微信 { detail: { value: ['a', 'b'] } }
支付宝 { detail: { value: ['a', 'b'] } }
抖音 { detail: { value: 'a,b' } }(字符串)

避坑指南:我曾经在抖音上做多选功能,直接用 value.includes('a') 判断,结果因为返回值是字符串,includes 方法直接报错。后来统一用 String(value).split(',') 处理,才解决问题。

小结

基础组件虽然简单,但跨平台时细节差异很多。我的建议是:

  • 视图容器:优先用 view,少用 scroll-viewswiper 的自定义指示器要提前测试
  • 基础内容text 注意选中功能,icon 用自定义图标,progress 属性名要适配
  • 表单组件button 的开放能力差异最大,input 的键盘类型要区分,checkbox 的返回值格式要统一处理

嗯,这些经验都是真金白银换来的。你写代码时多留个心眼,遇到奇怪的问题,先怀疑是不是平台差异。下一章咱们聊列表渲染和条件渲染,那个坑更多,到时候再细说。