8、自定义组件


  组件使用步骤:创建组件;声明组件;使用组件。

1、组件使用步骤

  组件使用步骤:创建组件;声明组件;使用组件。

  •   创建自定义组件,类似于页面,一个自定义组件由json、wxml、wxss、js 4个文件组成,可以在微信开发者工具中快速创建组件的文件结构。
    在这里插入图片描述
    项目下根目录新建一个文件夹“components”,
    然后在此文件夹下新建一个文件夹Tabs,
    选中Tabs所在行,右键选择component,
    然后输入Tabs即可自动创建名字为Tabs的四个类型的组件文件。
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 声明组件
      哪个页面要使用这个组件,就在要使用组件的页面的json文件中声明。
    在这里插入图片描述

  • 使用组件
    在demo6.json文件中声明后,就可以在demo6.wxml文件中使用。
    在这里插入图片描述

2. 组件案例:

  案例介绍:单击不同的类别,此类别处于激活状态。
  在页面.js文件中,事件回调函数 存放在data同层级下;组件.js文件中 事件回调函数存放在methods中。
文件树形结构图:
在这里插入图片描述
代码:

<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <view wx:for="{{tabs}}" wx:key="id" class="tabs_item {{item.isActive?'active':''}}" bindtap="handleItemTap" data-index="{{index}}">
      {{item.name}}
    </view>
  </view>
  <view class="tabs_content">内容</view>
</view>
/* components/Tabs/Tabs.wxss */
.tabs{}
.tabs_title{
  display: flex;
  padding:10rpx;
}
.tabs_item{
  flex:1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.active{
  color:red;
  border-bottom: 5rpx solid currentColor;
}
.tabs_content{}
// components/Tabs/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {

  },

  /**
   * 组件的初始数据
   */
  data: {
    tabs:[
      {
        id:0,
        name:"首页",
        isActive:true
      },
      {
        id:1,
        name:"原创",
        isActive:false
      },
      {
        id:2,
        name:"分类",
        isActive:false
      },
      {
        id:3,
        name:"关于",
        isActive:false
      }
    ]
  },

  /**
   * 组件的方法列表
   */
  methods: {
    handleItemTap(e){
      //获取被点击索引
      const {index}=e.currentTarget.dataset;
      //获取data中的数组
      //解构 对复杂类型进行解构的时候 相当于 复制了一份 变量的引用而已;下一行代码等于:let tabs=this.data.tabs;
      //最严谨的做法是 先重新拷贝一份数组 再对这个数组的备份进行处理,具体方法:加下面一行代码(作用为进行一次深拷贝)
      //let tabs=JSON.parse(JSON.stringify(this.data.tabs));
      let {tabs}=this.data;
      //循环数组(数组的forEach方法可以遍历数组,遍历数组的时候 ,v被修改,也会导致原数组被修改)
      tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
      this.setData({
        tabs
      })
    }
  }
})

运行截图:
在这里插入图片描述

3. 父组件向子组件传递数据

  父组件(页面)向子组件传递数据是通过 标签属性的方法来传递;
  子组件在.js文件properties中接收;
  把这个数据当成是data中的数据直接使用即可。
案例:
文件使用树形结构图
在这里插入图片描述
代码:
父组件

<!--pages/demo06/demo06.wxml-->
<Tabs aaa="aksjdkf"></Tabs>

子组件接收:

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

  data: {
  },
  methods: {
  }
})

子组件使用:

<!--components/Tabs/Tabs.wxml-->
<view>{{aaa}}</view>

运行截图:
在这里插入图片描述

4. 子组件向父组件传递数据

  子组件向父组件传递数据;子组件有想要传回父组件的值,触发父组件自定义函数,同时将数据传递给父组件。this.triggerEvent("父组件自定义事件的名称",要传递的参数)
案例:
分析:父组件将tabs数组传给子组件,子组件得以显示分类类别,当切换不同分类类别时,需更该tabs数组中的内容,假如在子组件中直接修改,相当于子组件有一份tabs数组的拷贝值,修改的只是这个拷贝值内容,并不会更改父组件tabs数组,所以在数据更改时,需要触发父组件函数,并传递数据、在父组件中修改数据。

文件使用树形结构图:
在这里插入图片描述

<!--pages/demo06/demo06.wxml-->
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange"></Tabs>
// pages/demo06/demo06.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){
    const {index}=e.detail;
    let {tabs}=this.data;
    tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
    this.setData({
      tabs
    })
  }
})
<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <view wx:for="{{tabs}}" wx:key="id" class="tabs_item {{item.isActive?'active':''}}" bindtap="handleItemTap" data-index="{{index}}">
      {{item.name}}
    </view>
  </view>
  <view class="tabs_content">内容</view>
</view>
/* components/Tabs/Tabs.wxss */
.tabs{}
.tabs_title{
  display: flex;
  padding:10rpx;
}
.tabs_item{
  flex:1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.active{
  color:red;
  border-bottom: 5rpx solid currentColor;
}
.tabs_content{}
// components/Tabs/Tabs.js
Component({
  /**
   * 里面存放的是要从父组件中接收的数据
   */
  properties: {
    tabs:{
      type:Array,
      value:[]
    }
  },

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

  /**
   * 组件的方法列表
   */
  methods: {
    handleItemTap(e){
      const {index}=e.currentTarget.dataset;
      this.triggerEvent("itemChange",{index});
    }
  }
})

运行截图:
在这里插入图片描述

5. slot

  slot标签 其实就是一个占位符 插槽。
  等到 父组件调用 子组件的时候 再传递 标签过来 最终这些被传递来的标签会替换 slot 插槽的位置
案例:根据类别修改下面内容
部分代码与上文 子向父传递数据类似 ,下面只给出有更改的文档:

<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <view wx:for="{{tabs}}" wx:key="id" class="tabs_item {{item.isActive?'active':''}}" bindtap="handleItemTap" data-index="{{index}}">
      {{item.name}}
    </view>
  </view>
    <slot></slot>
</view>
<!--pages/demo06/demo06.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>

运行截图:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值