uni-app 内置组件(下)
上一篇学了基础组件,本文延展到表单与交互组件,它们是做登录注册、设置页、搜索框的主力。
表单组件有一个共同点,数据绑定用 v-model,和 Vue 完全一致,这也是 uni-app 在表单上比原生小程序好写很多的地方。
input 输入框
最常用的表单组件,支持单行文本、密码、数字等:
<template>
<input
class="input"
v-model="phone"
type="number"
maxlength="11"
placeholder="请输入手机号"
/>
</template>
<script setup>
import { ref } from 'vue'
const phone = ref('')
</script>
常用属性速查:
| 属性 | 说明 |
|---|---|
type |
text / number / password 等 |
maxlength |
最大输入长度 |
placeholder |
占位提示文字 |
confirm-type |
键盘右下角按钮文字,如 done / search |
disabled |
是否禁用 |
常用事件:
@input,输入时触发@confirm,点击键盘确认键时触发,适合搜索场景
textarea 多行文本
多行文本输入,长按输入框区域还可以唤出系统菜单:
<textarea class="textarea" v-model="content" placeholder="请输入内容" :maxlength="200" />
checkbox 与 checkbox-group 复选
单独一个 checkbox 没有意义,要搭配 checkbox-group 容器,@change 事件返回选中的 value 数组:
<template>
<checkbox-group @change="onHobbyChange">
<label v-for="item in hobbies" :key="item.value">
<checkbox :value="item.value" />{{ item.name }}
</label>
</checkbox-group>
</template>
<script setup>
import { ref } from 'vue'
const hobbies = [
{ value: 'code', name: '写代码' },
{ value: 'game', name: '打游戏' },
{ value: 'read', name: '读书' }
]
const selectedHobbies = ref([])
function onHobbyChange(e) {
selectedHobbies.value = e.detail.value
}
</script>
radio 与 radio-group 单选
结构同上,radio-group 包住一组 radio,@change 返回选中的 value(单选字符串):
<template>
<radio-group @change="onGenderChange">
<label><radio value="male" checked />男</label>
<label><radio value="female" />女</label>
</radio-group>
</template>
<script setup>
function onGenderChange(e) {
console.log('选择了:', e.detail.value)
}
</script>
提示:label 组件可以扩大点击范围,文字点哪里都能选中,体验更好。
picker 滚动选择器
底部弹出的滚动选择器,手机上比下拉框好用得多,mode 决定类型:
| mode | 功能 | 返回值 |
|---|---|---|
| selector | 普通选择器 | index(下标) |
| date | 日期选择 | 日期字符串,如 2026-08-15 |
| time | 时间选择 | 时间字符串,如 12:30 |
| region | 省市区三级选择 | 数组,如 [‘广东省’,’广州市’] |
<template>
<picker mode="selector" :range="range" @change="onPickerChange">
<view>{{ range[index] }}</view>
</picker>
</template>
<script setup>
import { ref } from 'vue'
const range = ['早餐', '午餐', '晚餐']
const index = ref(0)
function onPickerChange(e) {
index.value = Number(e.detail.value)
}
</script>
日期选择的用法,直接把选中的日期显示在页面上:
<template>
<picker mode="date" :value="date" @change="onDateChange">
<view>生日:{{ date }}</view>
</picker>
</template>
<script setup>
import { ref } from 'vue'
const date = ref('2000-01-01')
function onDateChange(e) {
date.value = e.detail.value
}
</script>
switch 与 slider
switch 开关,常用于设置项的开关,直接 v-model 绑定布尔值:
<switch v-model="notifyEnabled" />
slider 滑块,常用于音量、亮度调节,@change 返回当前值:
<slider min="0" max="100" @change="onVolumeChange" />
button 按钮
比 HTML 的 button 多了移动端专属的 open-type:
| 属性 | 说明 |
|---|---|
type |
primary / default / warn |
size |
default / mini |
plain |
镂空(透明底)样式 |
loading |
显示加载中图标 |
disabled |
禁用 |
open-type |
share(唤起分享)、contact 等 |
<button type="primary" size="mini" loading>提交中</button>
<button open-type="share">分享给好友</button>
长列表怎么渲染
长列表(商品列表、消息列表)用**scroll-view + v-for** 就够了,记得写 :key:
<scroll-view class="list" scroll-y @scrolltolower="loadMore">
<view class="item" v-for="item in list" :key="item.id">
{{ item.title }}
</view>
</scroll-view>
注意:网上有些教程提到的 list-view、recycle-list 长列表组件,只在 App 端的 nvue 页面里可用,普通页面(H5、小程序)用不了,新手直接用 scroll-view + v-for 即可,性能不够时再考虑其他方案。
扩展组件从哪来
内置组件只覆盖基础元素,更复杂的组件(日历、富文本、下拉刷新等)来自插件市场。插件市场的组件统一装在 uni_modules/ 目录,用的时候在插件市场网页点「使用 HBuilderX 导入插件」即可,或者直接在 HBuilderX 的项目右键菜单里打开插件市场搜索。
比如过渡动画 uni-transition、下拉刷新 uni-refresh 都属于这类扩展组件,安装后在页面里就能当普通标签用。
综合示例:注册表单
用学过的组件拼一个注册表单,数据绑定、事件处理一次看全:
<template>
<view class="page">
<input class="field" v-model="form.username" placeholder="用户名" />
<input class="field" v-model="form.password" type="password" placeholder="密码" />
<radio-group class="field" @change="onGenderChange">
<label><radio value="male" checked />男</label>
<label><radio value="female" />女</label>
</radio-group>
<picker class="field" mode="date" :value="form.birthday" @change="onBirthdayChange">
<view>生日:{{ form.birthday }}</view>
</picker>
<view class="field">
<checkbox-group @change="onAgreeChange">
<label><checkbox value="agree" />同意用户协议</label>
</checkbox-group>
</view>
<button type="primary" @click="onRegister">注册</button>
</view>
</template>
<script setup>
import { ref } from 'vue'
const form = ref({
username: '',
password: '',
gender: 'male',
birthday: '2000-01-01',
agree: false
})
function onGenderChange(e) {
form.value.gender = e.detail.value
}
function onBirthdayChange(e) {
form.value.birthday = e.detail.value
}
function onAgreeChange(e) {
form.value.agree = e.detail.value.includes('agree')
}
function onRegister() {
if (!form.value.username || !form.value.password) {
uni.showToast({ title: '请填写完整信息', icon: 'none' })
return
}
if (!form.value.agree) {
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
return
}
console.log('注册数据:', form.value)
uni.showToast({ title: '注册成功' })
}
</script>
<style scoped>
.page {
padding: 40rpx;
}
.field {
display: flex;
align-items: center;
padding: 24rpx 0;
border-bottom: 1rpx solid #eee;
margin-bottom: 20rpx;
}
</style>
总结
| 组件 | 绑定方式 | 常见场景 |
|---|---|---|
input / textarea |
v-model | 输入框、搜索框 |
checkbox / radio |
父容器 @change | 多选、单选 |
picker |
mode 区分选择类型 | 下拉选择、日期 |
switch / slider |
v-model / @change | 开关、滑块 |
button |
@click | 提交、分享 |
| 长列表 | scroll-view + v-for | 列表页 |
| 复杂组件 | uni_modules 插件 | 日历、富文本 |
一句话总结:表单组件的数据绑定和 Vue 一模一样,v-model 双向绑定,@change 和 @click 处理事件,个别组件(picker、radio)的选中值藏在 e.detail 里,遇到复杂组件就去插件市场找现成的。