微信小程序入门学习教程,从入门到精通,自定义组件与第三方 UI 组件库(以 Vant Weapp 为例) (16)

自定义组件与第三方 UI 组件库(以 Vant Weapp 为例)

适用于微信小程序开发


一、组件化开发

1.1 什么是组件化开发

组件化开发是将 UI 拆分为独立、可复用的模块(组件),每个组件拥有自己的结构(WXML)、样式(WXSS)、逻辑(JS)和配置(JSON)。组件之间通过 属性(properties)事件(events)插槽(slots) 进行通信。

1.2 组件化开发的优势

  • 提高代码复用性
  • 便于团队协作
  • 降低维护成本
  • 逻辑清晰,结构解耦

二、自定义组件

2.1 创建自定义组件

步骤:
  1. 在项目中新建文件夹(如 components/my-button
  2. 创建四个文件:my-button.jsmy-button.jsonmy-button.wxmlmy-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(推荐)
  1. 初始化 npm(如未初始化):

    bash 复制代码
    npm init -y
  2. 安装 vant-weapp:

    bash 复制代码
    npm i @vant/weapp -S --production
  3. 微信开发者工具 → 工具 → 构建 npm

  4. 勾选"使用 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),对高频业务逻辑封装为自定义业务组件,实现"原子组件 + 业务组件"双层架构。


✅ 以上内容涵盖语法细节、完整案例、注释说明及综合实战,适用于微信小程序开发者系统学习组件开发。

相关推荐
trsoliu3 小时前
多仓库 Workspace 协作机制完整方案
前端
Rock_yzh3 小时前
AI学习日记——深度学习
人工智能·python·深度学习·神经网络·学习
@小张要努力3 小时前
STM32学习记录-0.1 STM32外设
stm32·嵌入式硬件·学习
啦工作呢3 小时前
数据可视化 ECharts
前端·信息可视化·echarts
NoneSL3 小时前
Uniapp UTS插件开发实战:引入第三方SDK
前端·uni-app
全栈小53 小时前
【小程序】微信开发者工具上调用api接口可以,到了线上调用发现提示wx.request调用报错,原来是https协议问题
网络协议·小程序·https
trsoliu3 小时前
Claude Code Templates
前端·人工智能
wangpq3 小时前
使用rerender-spa-plugin在构建时预渲染静态HTML文件优化SEO
前端·javascript·vue.js
KongHen3 小时前
完美解决请求跨域问题
前端