自定义组件与第三方 UI 组件库(以 Vant Weapp 为例)
适用于微信小程序开发
一、组件化开发
1.1 什么是组件化开发
组件化开发是将 UI 拆分为独立、可复用的模块(组件),每个组件拥有自己的结构(WXML)、样式(WXSS)、逻辑(JS)和配置(JSON)。组件之间通过 属性(properties) 、事件(events) 和 插槽(slots) 进行通信。
1.2 组件化开发的优势
- 提高代码复用性
- 便于团队协作
- 降低维护成本
- 逻辑清晰,结构解耦
二、自定义组件
2.1 创建自定义组件
步骤:
- 在项目中新建文件夹(如
components/my-button
) - 创建四个文件:
my-button.js
、my-button.json
、my-button.wxml
、my-button.wxss
案例:自定义按钮组件
components/my-button/my-button.json
json
{
"component": true,
"usingComponents": {}
}
component: true
表示这是一个组件。
components/my-button/my-button.js
javascript
Component({
// 组件属性定义
properties: {
text: {
type: String,
value: '默认按钮'
},
type: {
type: String,
value: 'primary' // primary / default
}
},
// 组件内部数据
data: {
isClicked: false
},
// 组件方法
methods: {
handleClick() {
this.setData({ isClicked: true });
// 触发自定义事件,通知父组件
this.triggerEvent('tap', { text: this.properties.text });
}
}
});
components/my-button/my-button.wxml
xml
<view
class="my-button {{type}} {{isClicked ? 'clicked' : ''}}"
bindtap="handleClick"
>
{{text}}
</view>
components/my-button/my-button.wxss
css
.my-button {
padding: 10rpx 20rpx;
border-radius: 8rpx;
display: inline-block;
text-align: center;
}
.primary {
background-color: #1989fa;
color: white;
}
.default {
background-color: #f5f5f5;
color: #333;
}
.clicked {
opacity: 0.7;
}
2.2 使用自定义组件
pages/index/index.json
json
{
"usingComponents": {
"my-button": "/components/my-button/my-button"
}
}
pages/index/index.wxml
xml
<view class="container">
<my-button
text="点击我"
type="primary"
bind:tap="onMyButtonTap"
/>
</view>
pages/index/index.js
javascript
Page({
onMyButtonTap(e) {
console.log('按钮被点击,内容:', e.detail.text);
}
});
三、Vant Weapp 组件库
3.1 安装 Vant Weapp
方法一:通过 npm(推荐)
-
初始化 npm(如未初始化):
bashnpm init -y
-
安装 vant-weapp:
bashnpm i @vant/weapp -S --production
-
微信开发者工具 → 工具 → 构建 npm
-
勾选"使用 npm 模块"
方法二:手动下载(不推荐)
从 GitHub 下载 dist 目录,放入项目如 miniprogram_npm/@vant/weapp/
3.2 引入组件
pages/index/index.json
json
{
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"van-cell": "@vant/weapp/cell/index",
"van-cell-group": "@vant/weapp/cell-group/index"
}
}
四、Vant Weapp 核心组件介绍
4.1 Button 按钮
属性(properties)
type
: 按钮类型(primary / success / danger / default)loading
: 是否加载中disabled
: 是否禁用
事件(events)
bind:click
:点击事件
插槽(slots)
- 默认插槽:按钮内容
案例:
xml
<van-button type="primary" bind:click="handleVantClick">
Vant 按钮
</van-button>
javascript
Page({
handleVantClick() {
wx.showToast({ title: 'Vant 按钮被点击' });
}
});
4.2 Cell 单元格
常用属性:
title
:左侧标题value
:右侧内容is-link
:是否展示右侧箭头
案例:
xml
<van-cell-group>
<van-cell title="用户名" value="张三" />
<van-cell title="设置" is-link bind:click="goToSetting" />
</van-cell-group>
五、组件的属性、事件与插槽
5.1 属性(Properties)
- 父组件通过属性向子组件传递数据
- 支持类型校验、默认值、观察器(observer)
示例:带 observer 的属性
javascript
properties: {
count: {
type: Number,
value: 0,
observer(newVal, oldVal) {
console.log('count 从', oldVal, '变为', newVal);
}
}
}
5.2 事件(Events)
- 子组件通过
triggerEvent
触发事件 - 父组件通过
bind:eventName
监听
示例:
javascript
// 子组件
this.triggerEvent('change', { id: 123 });
// 父组件
<my-component bind:change="handleChange" />
5.3 插槽(Slots)
- 默认插槽:
<slot />
- 具名插槽:
<slot name="header" />
子组件模板:
xml
<view class="card">
<slot name="header"></slot>
<slot></slot> <!-- 默认插槽 -->
</view>
父组件使用:
xml
<my-card>
<view slot="header">标题</view>
<text>内容区域</text>
</my-card>
六、业务组件开发实践
场景:封装一个"用户信息卡片"业务组件
components/user-card/user-card.json
json
{
"component": true,
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
}
components/user-card/user-card.js
javascript
Component({
properties: {
avatar: String,
name: String,
level: {
type: Number,
value: 1
}
},
methods: {
onEdit() {
this.triggerEvent('edit', { name: this.data.name });
}
}
});
components/user-card/user-card.wxml
xml
<view class="user-card">
<image class="avatar" src="{{avatar}}" mode="aspectFill" />
<view class="info">
<text class="name">{{name}}</text>
<text class="level">等级:{{level}}</text>
</view>
<van-button size="mini" bind:click="onEdit">编辑</van-button>
</view>
components/user-card/user-card.wxss
css
.user-card {
display: flex;
align-items: center;
padding: 20rpx;
border-bottom: 1rpx solid #eee;
}
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
}
.info {
flex: 1;
}
.name {
font-weight: bold;
display: block;
}
父页面使用:
xml
<user-card
avatar="/images/avatar.png"
name="李四"
level="5"
bind:edit="handleEditUser"
/>
七、综合性案例:商品列表页(结合自定义组件 + Vant)
功能:
- 使用 Vant 的 Cell 展示商品
- 自定义"加入购物车"按钮
- 点击商品跳转详情
页面结构:
pages/product-list/product-list.json
json
{
"usingComponents": {
"van-cell": "@vant/weapp/cell/index",
"van-cell-group": "@vant/weapp/cell-group/index",
"add-cart-btn": "/components/add-cart-btn/add-cart-btn"
}
}
pages/product-list/product-list.js
javascript
Page({
data: {
products: [
{ id: 1, name: 'iPhone 15', price: 5999 },
{ id: 2, name: 'MacBook Pro', price: 12999 }
]
},
onAddToCart(e) {
const product = this.data.products.find(p => p.id === e.detail.id);
wx.showToast({ title: `已添加 ${product.name}` });
},
goToDetail(e) {
const id = e.currentTarget.dataset.id;
wx.navigateTo({ url: `/pages/detail/detail?id=${id}` });
}
});
pages/product-list/product-list.wxml
xml
<van-cell-group>
<van-cell
wx:for="{{products}}"
wx:key="id"
title="{{item.name}}"
value="¥{{item.price}}"
is-link
data-id="{{item.id}}"
bind:click="goToDetail"
>
<add-cart-btn
slot="right-icon"
product-id="{{item.id}}"
bind:add="onAddToCart"
/>
</van-cell>
</van-cell-group>
components/add-cart-btn/add-cart-btn.js
javascript
Component({
properties: {
productId: Number
},
methods: {
handleAdd() {
this.triggerEvent('add', { id: this.properties.productId });
}
}
});
components/add-cart-btn/add-cart-btn.wxml
xml
<van-button size="mini" type="success" bind:click="handleAdd">+</van-button>
八、本章小结
知识点 | 说明 |
---|---|
组件化开发 | 模块化、复用、解耦 |
自定义组件 | 四文件结构,properties/events/slots |
Vant Weapp | 丰富 UI 组件,提升开发效率 |
属性 | 父传子,支持类型校验与 observer |
事件 | 子传父,通过 triggerEvent |
插槽 | 内容分发,支持默认与具名 |
业务组件 | 封装领域逻辑,提升复用性 |
建议:在实际项目中,优先使用成熟的 UI 库(如 Vant Weapp),对高频业务逻辑封装为自定义业务组件,实现"原子组件 + 业务组件"双层架构。
✅ 以上内容涵盖语法细节、完整案例、注释说明及综合实战,适用于微信小程序开发者系统学习组件开发。