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
})
}
})