三、核心组件详解
3.1 按钮组件 Button
按钮是用户交互中最基础的组件,Vant提供了多种按钮样式。
<template>
<!-- 按钮类型 -->
<van-button type="primary">主要按钮</van-button>
<van-button type="success">成功按钮</van-button>
<van-button type="danger">危险按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="default">默认按钮</van-button>
<!-- 按钮尺寸 -->
<van-button type="primary" size="large">大号按钮</van-button>
<van-button type="primary" size="normal">普通按钮</van-button>
<van-button type="primary" size="small">小型按钮</van-button>
<van-button type="primary" size="mini">迷你按钮</van-button>
<!-- 块级按钮(占满父容器宽度) -->
<van-button type="primary" block>块级按钮</van-button>
<!-- 方形按钮 -->
<van-button type="primary" square>方形按钮</van-button>
<!-- 禁用状态 -->
<van-button type="primary" disabled>禁用按钮</van-button>
<!-- 加载状态 -->
<van-button type="primary" loading>加载中</van-button>
<!-- 图标按钮 -->
<van-button type="primary" icon="star-o">收藏</van-button>
<van-button type="primary" icon="https://example.com/icon.png">自定义图标</van-button>
</template>
3.2 单元格组件 Cell
单元格是移动端列表布局的核心组件,常用于信息展示和导航。
<template>
<!-- 基础单元格 -->
<van-cell title="单元格标题" value="内容" />
<van-cell title="单元格标题" label="描述信息" value="内容" />
<!-- 带图标的单元格 -->
<van-cell title="单元格" icon="location-o" />
<!-- 带右侧箭头的单元格(常用于导航) -->
<van-cell title="单元格" is-link to="/page" />
<!-- 自定义内容 -->
<van-cell title="单元格">
<template #value>
<van-tag type="danger">标签</van-tag>
</template>
</van-cell>
<!-- 单元格组 -->
<van-cell-group title="分组标题">
<van-cell title="单元格1" value="内容1" />
<van-cell title="单元格2" value="内容2" />
<van-cell title="单元格3" value="内容3" />
</van-cell-group>
</template>
3.3 表单组件 Form
Vant提供了完整的表单组件体系,包括输入框、选择器、开关等。
<template>
<van-form @submit="onSubmit">
<van-cell-group inset>
<!-- 输入框 -->
<van-field
v-model="formData.username"
name="username"
label="用户名"
placeholder="请输入用户名"
:rules="[{ required: true, message: '请填写用户名' }]"
/>
<!-- 密码输入框 -->
<van-field
v-model="formData.password"
type="password"
name="password"
label="密码"
placeholder="请输入密码"
:rules="[{ required: true, message: '请填写密码' }]"
/>
<!-- 数字输入框 -->
<van-field
v-model="formData.age"
type="digit"
label="年龄"
placeholder="请输入年龄"
/>
<!-- 带右侧按钮的输入框 -->
<van-field
v-model="formData.code"
label="验证码"
placeholder="请输入验证码"
>
<template #button>
<van-button size="small" type="primary" @click="sendCode">发送验证码</van-button>
</template>
</van-field>
<!-- 开关 -->
<van-field name="switch" label="开关">
<template #input>
<van-switch v-model="formData.switch" />
</template>
</van-field>
</van-cell-group>
<div style="margin: 16px;">
<van-button round block type="primary" native-type="submit">提交</van-button>
</div>
</van-form>
</template>
<script setup>
import { reactive } from 'vue';
import { showToast } from 'vant';
const formData = reactive({
username: '',
password: '',
age: '',
switch: false,
});
const onSubmit = (values) => {
showToast('提交成功');
console.log(values);
};
const sendCode = () => {
showToast('验证码已发送');
};
</script>
3.4 列表组件 List
List组件用于实现无限滚动加载,是移动端长列表场景的核心组件。
<template>
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell v-for="item in list" :key="item.id" :title="item.title" />
</van-list>
</template>
<script setup>
import { ref } from 'vue';
import { showToast } from 'vant';
const list = ref([]);
const loading = ref(false);
const finished = ref(false);
let page = 1;
const onLoad = async () => {
// 模拟异步请求
const newData = await fetchData(page);
list.value.push(...newData);
loading.value = false;
if (newData.length === 0) {
finished.value = true;
}
page++;
};
</script>
3.5 弹出层组件
Vant提供了多种弹出层组件,满足不同场景的需求。
3.5.1 动作面板 ActionSheet
<template>
<van-action-sheet v-model:show="showActionSheet" :actions="actions" @select="onSelect" />
</template>
<script setup>
import { ref } from 'vue';
import { showToast } from 'vant';
const showActionSheet = ref(false);
const actions = [
{ name: '选项一', value: 1 },
{ name: '选项二', value: 2 },
{ name: '选项三', value: 3, subname: '描述信息' },
{ name: '选项四', value: 4, disabled: true },
];
const onSelect = (item) => {
showToast(`选中了${item.name}`);
showActionSheet.value = false;
};
</script>
3.5.2 对话框 Dialog
<script setup>
import { showDialog, showConfirmDialog } from 'vant';
// 提示对话框
const showAlert = () => {
showDialog({
title: '标题',
message: '内容',
confirmButtonText: '知道了',
});
};
// 确认对话框
const showConfirm = async () => {
try {
await showConfirmDialog({
title: '确认',
message: '确定要删除吗?',
});
showToast('点击了确认');
} catch {
showToast('点击了取消');
}
};
</script>
3.5.3 轻提示 Toast
<script setup>
import { showToast, showLoadingToast, showSuccessToast, showFailToast } from 'vant';
// 普通提示
showToast('提示内容');
// 成功提示
showSuccessToast('操作成功');
// 失败提示
showFailToast('操作失败');
// 加载提示
showLoadingToast({
message: '加载中...',
forbidClick: true, // 禁止点击
});
// 自定义位置
showToast({
message: '顶部提示',
position: 'top',
});
</script>
3.6 图片上传组件 Uploader
<template>
<van-uploader v-model="fileList" :max-count="5" :after-read="afterRead" />
</template>
<script setup>
import { ref } from 'vue';
import { showToast } from 'vant';
const fileList = ref([]);
const afterRead = (file) => {
// 模拟上传请求
const formData = new FormData();
formData.append('file', file.file);
// 上传逻辑...
showToast('上传成功');
};
</script>
四、进阶用法
4.1 组件注册方式
Vant支持多种组件注册方式:
方式一:全局注册
import { Button } from 'vant';
import { createApp } from 'vue';
const app = createApp();
app.use(Button);
方式二:全量注册
import Vant from 'vant';
app.use(Vant);
方式三:局部注册
<script setup>
import { Button } from 'vant';
// 在<script setup>中可以直接使用,无需手动注册
</script>
<template>
<van-button>按钮</van-button>
</template>
4.2 组件插槽
Vant提供了丰富的组件插槽,支持个性化定制。
<template>
<!-- 自定义复选框图标 -->
<van-checkbox v-model="checked">
<template #icon="props">
<img :src="props.checked ? activeIcon : inactiveIcon" />
</template>
</van-checkbox>
<!-- 自定义导航栏内容 -->
<van-nav-bar title="标题">
<template #left>
<van-icon name="arrow-left" @click="onClickLeft" />
</template>
<template #right>
<van-icon name="ellipsis" />
</template>
</van-nav-bar>
</template>
4.3 组件实例方法
Vant中的许多组件提供了实例方法,需要通过ref调用。
<template>
<van-checkbox v-model="checked" ref="checkboxRef">复选框</van-checkbox>
<van-button @click="toggleCheckbox">切换</van-button>
</template>
<script setup>
import { ref } from 'vue';
const checked = ref(false);
const checkboxRef = ref(null);
const toggleCheckbox = () => {
checkboxRef.value?.toggle();
};
</script>
4.4 组合式API
Vant底层依赖了@vant/use包,提供了一系列实用的组合式API。
useCountDown示例:
<script setup>
import { useCountDown } from '@vant/use';
const { current, isRunning, start, reset } = useCountDown({
time: 60 * 1000,
onFinish: () => {
showToast('倒计时结束');
},
});
// 开始倒计时
const startCountdown = () => {
start();
};
</script>
<template>
<div>{
{ current }}秒</div>
<van-button @click="startCountdown">开始倒计时</van-button>
</template>