Vant4是一套面向Vue3的移动端组件库,展示组件是其中使用频率最高的一类,包括Cell单元格、Tag标签、Badge徽标、Image图片、Skeleton骨架屏、Empty空状态等。这些组件看起来简单,但真正上手时常常遇到按需引入不生效、样式覆盖失败、图片懒加载异常等问题。这篇文章从引入方式讲起,把常用展示组件的核心用法和易错点梳理清楚。

一、Vant4的安装与组件引入
Vant4只支持Vue3,如果项目还是Vue2,需要降级使用Vant2。安装命令很简单,在项目根目录执行npm install vant即可,默认安装的就是最新的Vant4版本。安装完成后,组件的引入分为全量引入和按需引入两种方式。
全量引入适合快速原型开发,直接在main.ts中注册所有组件:
import { createApp } from 'vue';
import Vant from 'vant';
import 'vant/lib/index.css';
import App from './App.vue';
const app = createApp(App);
app.use(Vant);
app.mount('#app');
按需引入是生产环境更推荐的方式,能显著减少打包体积。Vant4官方推荐配合unplugin-vue组件自动按需导入插件使用,只需在vite.config.ts中配置:
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import VantResolver from '@vant/auto-import-resolver';
export default {
plugins: [
vue(),
Components({
resolvers: [VantResolver()],
}),
],
};
配置完成后,模板里直接写<van-cell>这样的标签即可,插件会自动分析依赖并注入样式,不需要再手动import样式文件。这里有个常见的坑:如果同时在main.ts里全量引入了Vant,又用了自动按需插件,可能产生样式重复覆盖,建议二选一。
二、常用展示组件的核心用法
Cell单元格
Cell是移动端页面里最常见的列表项组件,通常搭配van-cell-group使用形成分组效果。它支持标题、描述、右侧文案、图标等属性,还提供了value插槽和right-icon插槽用于自定义内容:
<van-cell-group inset>
<van-cell title="订单中心" value="查看全部" is-link />
<van-cell title="收货地址" label="默认地址:北京市朝阳区" is-link />
<van-cell title="联系客服">
<template #right-icon>
<van-icon name="phone-o" />
</template>
</van-cell>
</van-cell-group>
inset属性会让分组卡片化并左右留出边距,视觉上更贴近现代设计风格。is-link会自动显示右侧箭头,常用于可跳转的列表项。需要注意的是,Cell的value属性只接受纯文本,如果内容包含按钮或图片,务必用默认插槽而不是value属性,否则内容会被当作文本渲染。
Skeleton骨架屏
骨架屏用于在数据加载完成前展示占位元素,减少白屏等待的焦虑感。核心属性是loading和title,配合数据请求状态切换即可:
<van-skeleton title :row="3" :loading="loading">
<div class="content">{ { realContent } }</div>
</van-skeleton>
loading为true时展示骨架,为false时展示插槽内的真实内容。row控制占位行数,row-width可以传数组让每行宽度不同,例如:row-width="['100%', '60%', '30%']",这样骨架的形态更接近真实内容,体验更自然。
Image图片与Empty空状态
van-image支持圆角、填充模式、加载失败占位等能力,其中fit属性控制裁剪方式,常用值有cover和contain。lazy-load属性开启懒加载,但必须保证页面存在滚动容器,否则IntersectionObserver观察不到触发时机。Empty组件用于列表无数据时的提示,可以通过image插槽放自定义插画,description属性设置文案。
三、高频踩坑点与解决方案
样式覆盖不生效
覆盖Vant4组件样式时发现写的CSS不起作用,多半是优先级问题。Vant的样式类名作用在根元素上,直接用类名选择器可能因为specificity不够而失败。正确做法是使用深度选择器穿透组件作用域:
/* scoped style 中穿透 */
:deep(.van-cell__title) {
color: #333;
font-weight: 600;
}
另外Vant4提供了ConfigProvider组件做主题定制,通过CSS变量覆盖比硬改样式更优雅,例如--van-cell-title-font-size这类变量可以统一控制字号,维护成本远低于逐个覆盖。
按需引入后组件不渲染
如果用了unplugin-vue-components但页面上组件没渲染,首先检查依赖是否安装了@vant/auto-import-resolver,其次确认vite.config.ts修改后重启了开发服务器。还有一种情况是组件名写错,比如把<van-cell>写成<vancell>,插件不会报错但无法识别。此外TS项目中如果类型提示缺失,可以在tsconfig或env.d.ts中引用vant/global.d.ts的类型声明。
Empty与Skeleton的使用边界
不少初学者分不清什么时候用Empty、什么时候用Skeleton。简单判断标准是:数据还在请求中用Skeleton占位,请求完成但结果为空用Empty提示。两者结合的典型写法是:
<van-skeleton :loading="loading" :row="3">
<van-empty v-if="list.length === 0" description="暂无数据" />
<van-cell-group v-else>
<van-cell v-for="item in list" :key="item.id" :title="item.name" />
</van-cell-group>
</van-skeleton>
这种结构能覆盖加载中、空数据、正常数据三种状态,是移动端列表页的标准范式。
四、使用建议
第一,优先使用插槽而不是属性传复杂内容,插槽在灵活性和可维护性上都优于拼字符串。第二,主题相关的调整尽量走CSS变量,避免大量深度选择器堆砌。第三,遇到组件行为不符合预期时,先看官方文档的Props说明,多数疑问在属性默认值里能找到答案,比如Cell的center属性默认false,不理解为什么内容顶部对齐时往往就是漏了它。掌握这些要点后,Vant4的展示组件基本可以做到即拿即用,不再被各种小问题反复困扰。