小程序 --- > Tab组件的封装

本文详细介绍了如何在小程序中封装一个Tab组件,包括组件引入、参数传递、事件绑定、值的父传子、子传父及插槽实现。通过实例展示了组件的使用和功能实现,帮助开发者更好地理解和创建自定义Tab组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Tabs组件的封装


1.1 组件的引入

使用自定义的组件很简单,只需在使用组件的页面的配置文件.json文件中配置.

// pages/goods_list/index.json
{
    "usingComponents":{
        "Tabs": "../../components/Tabs/Tabs"
    }
}

然后再.wxml文件中使用即可

<!-- pages/goods_list/index.wxml -->
<Tabs></Tabs>

1.2 向组件传递参数(父->子)

在父页面中首先有如下数据

// pages/goods_list/index.js
page({
    data:{
        tabs: [...]
    }
})

然后在使用组件的时候将参数带上

<!-- pages/goods_list/index.wxml -->
<Tabs tabs="{{tabs}}"></Tabs>

在组件中接收参数

// components/Tabs/Tab.js
Component({
    properties:{
        tabs:{
            type: Array,
            value: []
        }
    }
})

之后就可以使用参数了. 下面是使用参数的写的一个小栗子:

<view class="tabs">
	<view class="tabs_title">
    	<view wx:for="{{tabs}}" wx:key="id" class="title_item"></view>
    </view>
</view>

1.3 给组件绑定点击事件

关键在于bindtap

<!-- components/Tabs/Tabs.wxml -->
<view bindtap="handleItemTap" data-hello="world">
</view>

上述将传递的参数写在了data-hello中,然后js中写事件处理函数

// components/Tabs/Tab.js
Components({
    methods: {
        handleItemTap(e) {
            // 接收data-hello属性的值
            const { hello } = e.target.dataset;
        }
    }
})

1.4 向父级传递值(子->父)

在子组件的事件处理函数中调用微信提供的triggerEvent

// components/Tabs/Tabs.js
Component({
    methods:{
        handleItemTap(e) {
            const { hello } = e.target.dataset;
            this.triggerEvent("TabsItemChange", { hello })
        }
    }
})

以上实现了: 当点击子组件的view标签时,会像父组件传递一个 { hello: world}的字符串.下面在父组件调用Tabs组件的位写上一个接收该方法的函数

<!-- pages/goods_list/index.wxml -->
<Tabs tabs="{{tabs}}" bindTabsItemChange ="handleTabsItemChange"></Tabs>

以上在父组件中添加了一个事件处理函数的索引信息,下面在父组件的js文件中实现事件处理函数

// pages/goods_list/index.js
Page({
    handleTabsItemChange(e) {
        const {hello} = e.detail
        console.log(hello);
    }
})

1.5 插槽的实现

Tab栏的最基本功能是,根据点击的小tips,底下的内容跟着改变.这在设计Tabs组件的时候就该考虑到

<!-- components/Tabs/Tabs.wxml -->
<view class="tabs">
    <view class="tabs_title">
        <view wx:for="{{tabs}}" wx:key="id">
        	{{item.value}}
        </view>
    </view>
    <view class=”tabs_content>
        <!-- 注意此处实现插槽 -->
    	<slot></slot>
    </view>
</view>

在使用的时候,只需使用block标签替换插槽中的内容即可

<!-- pages/goods_list/index.wxml -->
<Tabs tabs="{{tabs}}">
    <block wx:if="{{tabs[0].isActive}}">综合</block>
    <block wx:elif="{{tabs[1].isActive}}">销量</block>
    <block wx:elif="{{tabs[2].isActive}}">价格</block>
</Tabs>

1.6 总体代码

包括组件的实现和调用

【组件的wxml】

<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive? 'active': ''}}"
    bindtap="handleItemTap"
    data-index="{{index}}"
    >{{item.value}}</view>
  </view>
  <view class="tabs_content">
    <slot></slot>
  </view>
</view>

【组件的js】

// components/Tabs/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    tabs: {
      type: Array,
      value: [],
    },
  },

  /**
   * 组件的初始数据
   */
  data: {},

  /**
   * 组件的方法列表
   */
  methods: {
    handleItemTap(e) {
      // 1. 获取点击的索引
      const { index } = e.target.dataset
      // 2. 触发父组件中的事件
      this.triggerEvent("TabsItemChange", {index})
    },
  },
})

【组件的样式】

/* components/Tabs/Tabs.wxss */
.tabs {}

.tabs_title {
  display: flex;
}

.title_item {
  flex:1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 15rpx 0;
}

.active{
  color: var(--themeColor);
  border-bottom: 5rpx solid currentColor;
}

【调用的wxml】

<!--pages/goods_list/index.wxml-->
<Tabs tabs="{{tabs}}" bindTabsItemChange="handleTabsItemChange">
  <block wx:if="{{tabs[0].isActive}}">综合</block>
  <block wx:elif="{{tabs[1].isActive}}">销量</block>
  <block wx:elif="{{tabs[2].isActive}}">价格</block>
</Tabs>

【调用的js】

// pages/goods_list/index.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
    tabs: [
      {
        id: 0,
        value: '综合',
        isActive: true,
      },
      {
        id: 1,
        value: '销量',
        isActive: false,
      },
      {
        id: 2,
        value: '价格',
        isActive: false,
      },
    ],
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(options)
  },

  // 标题的点击事件(从子组件传递过来)
  handleTabsItemChange(e) {
    const { index } = e.detail
    let { tabs } = this.data
    tabs.forEach((v, i) => (i == index ? (v.isActive = true) : (v.isActive = false)))
    this.setData({
      tabs
    })
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值