赞
踩
前言:组件是放在components文件夹内,页面是放在pages文件夹内,
页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
组件.js 文件中 存放事件回调函数的时候 必须要存在在 methods中!!!
不要搞混
通过一个实例进行讲解
先介绍自定义组件,稍后会涉及父子组件传参
效果图:
首先在components文件夹内新建一个文件,例如Tab,用来抽取公共头部,Tab可以像view标签一样被页面使用,即 <Tabs></Tabs>
要求:
子组件:wxml写需要在父组件中展示的内容
页面:在json中先引入子组件,再用标签呈现子组件
具体操作如下:
首先在Tab.wxml写点内容
<view class="tabs">
<view class="tabs_title">
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="hanldeItemTap"
data-index="{{index}}"
>
{{item.name}}
</view>
</view>
</view>
Tab.js文件,先模拟子组件自己模拟数据并操作
Component({ data: { tabs: [ { id: 0, name: "首页", isActive: true }, { id: 1, name: "原创", isActive: false } , { id: 2, name: "分类", isActive: false } , { id: 3, name: "关于", isActive: false } ] }, methods: { hanldeItemTap(e) { /* 1 绑定点击事件 需要在methods中绑定 2 获取被点击的索引 3 获取原数组 4 对数组循环 1 给每一个循环性 选中属性 改为 false 2 给当前的索引的 项 添加激活选中效果就可以 */ // 2 获取索引,解构赋值 const { index } = e.currentTarget.dataset; // 3 获取data中的数组 // 最严谨的做法:重新拷贝一份数组,再对这个数组的备份进行处理, let tabs=JSON.parse(JSON.stringify(this.data.tabs)); // 4 循环数组 // [].forEach 遍历数组 遍历数组的时候 修改了 v ,也会导致源数组被修改 tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); this.setData({ tabs }) } } })
页面使用Tabs自定义组件就很简单
需要在该页面文件夹下的json文件补充以下,记录组件
{
"usingComponents": {
"Tabs":"../../components/Tabs/Tabs"
}
}
wxml
<Tabs></Tabs>
wcss
.tabs_title{
display: flex;
padding: 10rpx 0;
}
.title_item{
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.active{
color:red;
border-bottom: 5rpx solid currentColor;
}
看起来是不是很简单呢
但是,传参呢?
现在我们开始做组件传参了!
具体如下:
页面通过标签属性给子组件传参,子组件通过properties接收,子组件通过触发事件向页面传参
页面(父):
向子组件传递数据:在子组件的标签(此标签在父组件内),例如tabs="{{tabs}}"
通过tabs属性传递页面中的定义的tabs数据。
接收子组件数据:在子组件的标签(此标签在父组件内即Tabs)上加入一个 自定义事件,注意做好对应关系才能接收数据,用下图可以说明
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
</Tabs>
接收子组件传递过来的数据时,注意要子组件进行传递时的父组件的方法名,也就是说如果子组件用的是itemChange进行传递,那么父组件需要用binditemChange来绑定父组件的方法进行接收。
子组件:
3. 从父接收数据: 子组件下有个properties,把这里面的数据当成是data中的数据直接用即可,里面存放的是从父组件中接收的数据,如下
properties: {
tabs:{
type:Array,
value:[]
}
}
//this.triggerEvent("父组件自定义事件的名称",要传递的参数)
this.triggerEvent("itemChange",{index});
Page({ data: { tabs: [ { id: 0, name: "首页", isActive: true }, { id: 1, name: "原创", isActive: false } , { id: 2, name: "分类", isActive: false } , { id: 3, name: "关于", isActive: false } ] }, // 自定义事件 用来接收子组件传递的数据的 handleItemChange(e) { // 接收传递过来的参数 const { index } = e.detail; let { tabs } = this.data; tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); this.setData({ tabs }) } })
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
</Tabs>
<view class="tabs">
<view class="tabs_title">
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="hanldeItemTap"
data-index="{{index}}"
>
{{item.name}}
</view>
</view>
</view>
// components/Tabs.js Component({ properties: { tabs:{ type:Array, value:[] } }, data: { }, methods: { hanldeItemTap(e){ const {index}=e.currentTarget.dataset; // 5 触发父组件中的自定义事件 同时传递数据给 this.triggerEvent("itemsChange",{index}); } } })
至此,我们就完成了自定义组件的使用和传参啦
总结一下内容!!
父组件要使用子组件的话,首先在json中引入,然后在页面中用子组件标签<子组件名></子组件名>
父组件向子组件传参通过自己页面内的子标签传递,通过子组件的传递的方法名进行绑定接收的方法
子组件向父组件传参通过绑定方法传递,通过properties进行接收。
还有一个点,如果将父组件的写在子组件标签内容的元素显示出来呢,这时候就用到slot
slot 标签 其实就是一个占位符 插槽,写在子组件内用来接收父组件通过标签传递过来的
等到父组件调用子组件的时候,再传递标签过来最终这些被传递的标签,就会替换 slot 插槽的位置
子组件wxml,增加一个slot
<view class="tabs"> <view class="tabs_title"> <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="hanldeItemTap" data-index="{{index}}" > {{item.name}} </view> </view> <view class="tabs_content"> <slot></slot> </view> </view>
父组件wxml,block就是要传递给子组件的内容,会替换slot
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
<block wx:if="{{tabs[0].isActive}}">0 </block>
<block wx:elif="{{tabs[1].isActive}}">1 </block>
<block wx:elif="{{tabs[2].isActive}}">2 </block>
<block wx:else>3</block>
</Tabs>
至此,完成小案例啦!你也快去试试吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。