微信小程序学习-自定义组件详解

自定义组件算是在学习微信程序开发过程中遇到的一个难点,首先我们需要明确我们为什么要使用自定义组件,在微信小程序中有很多提供的官方组件比如,viewtextimage等等,这些组件方便我们开发使用,因为我们会频繁使用这些组件来完成我们开发工作。所以我们自定义组件也是这个样子的,程序开发过程中存在许多相似的模块开发,我们可以在遇到每一个模块都进行一遍设计,但是这样的代码太过臃肿,不利于维护,所以就通过自定义组件,在需要的时候直接调用,代码更加简洁高效。接下来就一起看看我们是怎么自定义组件的吧。

1.创建自定义组件

我们首先在小程序文件夹目录下新建一个component文件夹,在component文件夹下新建一个自定义组件文件夹,我们自定义组件叫Tabs,我们将这个命名文件夹,随后右键选择新建Component,名字命名Tabs,开发者工具就帮我们建立四个文件。json wxml wxss js

在这里插入图片描述

2.声明组件

创建好了组件文件目录,我们需要声明组件,在Tbs.json中进行自定义组件声明

{
  "component": true,
  "usingComponents": {}
}

3.编辑组件

我们需要在wxml 文件中编写组件,在wxss 文件中编写组件样式

【Tabs.wxml】

<view class="tabs">
    	<view class="tabs_title">
        <view class="title_item active" >首页</view>    
        <view class="title_item">原创</view>    
        <view class="title_item">分类</view>    
        <view class="title_item">关于</view> 
        <view  
</view>

【Tabs.wxss】

.tabs{}
.tabs_title{
    display: flex;
    padding: 10rpx;
}
.title_item{
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
}
.active{
    color: red;
    border-bottom: 10rpx solid currentColor;
}
.tabs_content{}

4.调用组件

我们自定义组件定义好了,我们需要去调用,首先我们需要在需要的应用处声明引入组件,我们在我们demo16下引入组件,我们首先在demo16.json中进行如下引入声明

{
  "usingComponents": {
    "Tabs":"../../components/Tabs/Tabs"
  }
}

然后在demo16.wxml中引入就可以了

<Tabs ></Tabs>  

以上就可以完成一个基本的自定义组件,但是我们还想更多有趣的玩法操作呢?

首先我们现在用的自定义组件数据全部来自,Tabs,我们希望的是数据由父组件(demo16)传向子组件(Tabs),这样设计也更加灵活,同时子组件也可以向父组件传递信息,完成信息的交互。

5.自定义组件传参

【demo-wxml】

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

【demo-js】

// pages/demo16/demo16.js
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){
    //console.log(e);
    //接收参数
    const{index} =e.detail;
    //console.log(index)
    let {tabs} = this.data;
    console.log(tabs)
    //循环处理
    tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
    this.setData({
      tabs
    })
  }
})

通过以上代码我们可以看到我们在demo.js中的data中定义了数据,数据名tabs,类型是一个列表。通过自定义组件属性的方式将参数进行传递,那么接下来就是子组件对参数的接收。

【Tabs-JavaScript】

// components/Tabs/Tabs.js
Component({
  /**
   * 里面存放的是,要从父组件接收的数据
   * 
   */
  properties: {
    // //要接受数据的名称
    // aaa:{
    //   //type 要接受的数据类型
    //   type:String,
    //   //value 默认值
    //   value:""
    // }
    tabs:{
      type:Array,
      value:[]
    }

  },

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


  },

  /**
   1.页面.js文件中 存放事件回调函数的时候 存放在data同层级下的
   2.组件.js文件中 存放事件回调函数的时候必须要存在methods中
   */
  methods: {
    handleItemTap(e){
      /*
      1.绑定点击事件,需要在methods中绑定
      2.获取被点击的索引
      3.获取原数组
      对数组循环
        1.给每一个循环性选中的属性改为false
        2.给当前的索引的项添加激活选中效果就可以了
      4.点击触发事件
        触发父组件中的自定义事件 同时传递数据给父组件
        this.triggerEvent("父组件中自定义事件名称",要传递的参数)
      */ 
     
      console.log(e)
      //获取索引
      const {index}=e.currentTarget.dataset;
      this.triggerEvent("itemChange",{index});
      //获取data中数组
      //let {tabs} = this.data;
      //循环处理
      //tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
      // this.setData({
      //   tabs
      // })

    }

  }
})

子组件接收父组件的参数是在 JavaScript文件下的Component里面properties中接收,接收格式就是数据名称,数据类型还有默认值,接收道德数据和本身定义在data下的数据使用方式一样{{tabs}}即可。我们在程序中设定了一个点击的绑定事件,通过点击不同值,产生不同点击内容与显示效果。

【Tabs-wxml】

<view class="tabs">
        wx:for="{{tabs}}" 
        wx:key="id" 
        class="title_item {{item.isActive? 'active':''}}"
        bindtap="handleItemTap"
        data-index="{{index}}"
        >
            {{item.name}}
        </view>
          
    <!-- </view> -->
    <view class="tabs_content">
    <!-- slot 标签 只是一个占位符 插槽
        等到 父组件调用子组件的时候 再传递 标签过来 最终这些被传递的标签就会替换slot插槽位置
        -->
        <slot></slot>
        
    </view>  
</view>

我们希望将点击这件事的参数传回给父组件,通过this.triggerEvent("父组件中自定义事件名称",要传递的参数),进行传递,父组件中的事件进行接收binditemChange="handleItemChange",我们这里传递回去的是index,在父组件的回调函数中进行处理详情见【demo-js】,这样就完成了数据的传递。我们希望在点击不同的按钮显示不同的内容,我们使用wx:if判断,在子组件中我们用slot标签即可,这是一个占位符,等到 父组件调用子组件的时候 再传递 标签过来 最终这些被传递的标签就会替换slot插槽位置。回到【demo.wxml】,我们可以看到在Tabs中间定义的就是父组件要传递过来的数据。

由此我们完成了自定义组件的实验,并且实现了父组件,子组件的数据传递。我们看看结果吧。
在这里插入图片描述

在这里插入图片描述

可以看到,我们在点击分类的时候,分类效果处于激活状态,同时查看Tabs数据,看到tabs[2]的isActive是true,其他为false,实现类我们想要的功能。

6.小结

  1. 父组件通过属性向子组件传递参数,子组件通过propertie接收参数

  2. 子组件通过事件向父组件传递参数

  3. 父组件监听handleItemChange事件.

  4. 子组件通过itemChange事件触发父组件binditemChange

    自定义组件触发事件时,需要使用triggerEvent("父组件中自定义事件名称",要传递的参数)进行参数传递。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值