10. 自定义组件

类似vue或者react中的自定义组件

小程序允许我们使用自定义组件的方式来构建页面

10.1 创建自定义组件

类似于页面,一个自定义组件由.json/ .wxml / .wxss / .js 4个文件组成

可以在微信开发者工具中快速创建组件的文本结构

父组件的json文件:

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

父组件的wxml页面:

<Tabs></Tabs>

子组件的js文件

// components/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //要接收的数据的名称
    tabs: {
      type: Array, //要接收的数据类型
      value: []
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    tabs: [
      {
        id: 1,
        name: '首页',
        isActive: true
      }, {
        id: 2,
        name: '原创',
        isActive: false
      }, {
        id: 3,
        name: '分类',
        isActive: false
      }, {
        id: 4,
        name: '关于',
        isActive: false
      }
    ]
  },
  /**
   * 1.页面.js文件中存放事件的回调函数的时候 存放在data的同层级下!!
   * 2.组件.js文件中存放事件的回调函数的时候 必须要存放在methods中!
   */
  methods: {
    /*
    * 1.绑定点击事件,需要在methods中绑定
    * 2.获取被点击的索引
    * 3.获取原数组
    * 4.对数组循环
    *   4.1给每一个循环项选中属性改为false
    *   4.2给当前选中项的选中属性改为true
    * */
    handleItemTap(e){
      console.log('handleItemTap')
      //获取被点击的索引
      console.log(e.currentTarget.dataset);
      const {index} = e.currentTarget.dataset;
      //获取data中的数组
      //解构 对复杂类型进行解构的时候,复制了一份变量的引用而已
      //最严谨的做法,重新拷贝一种数组,再对这个数组的备份进行处理
      let {tabs} = this.data; //等同于:let tabs = this.data.tabs;

      //循环遍历数组
      //arr.forEach循环遍历数组,循环遍历数组的时候,修改了v,也会导致原数组被修改
      tabs.forEach((v, i) => {
        i===index?v.isActive=true:v.isActive=false;
      })

      this.setData({
        tabs
      })
    }
  }
})

子组件wxml页面:

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

10.2 父组件往子组件传值

父组件js

// pages/demoComponent/demoComponent.js
Page({
  data: {
    tabs: [
      {
        id: 1,
        name: '首页',
        isActive: true
      }, {
        id: 2,
        name: '原创',
        isActive: false
      }, {
        id: 3,
        name: '分类',
        isActive: false
      }, {
        id: 4,
        name: '关于',
        isActive: false
      }
    ]
  }
})

父组件json

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

父组件页面

<!--pages/demoComponent/demoComponent.wxml-->
<view>pages/demoComponent/demoComponent.wxml</view>
<view>1.父组件(页面)向子组件传递数据通过标签属性的方式来传递</view>
<Tabs tabs="{{tabs}}"></Tabs>

子组件js

// components/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //要接收的数据的名称
    tabs: {
      type: Array, //要接收的数据类型
      value: []
    }
  },

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

  },

  /**
   * 1.页面.js文件中存放事件的回调函数的时候 存放在data的同层级下!!
   * 2.组件.js文件中存放事件的回调函数的时候 必须要存放在methods中!
   */
  methods: {
   
  }
})

子组件页面

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

10.3 子组件往父组件传值

子组件wxml页面:

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

子组件js

// components/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //要接收的数据的名称
    tabs: {
      type: Array, //要接收的数据类型
      value: []
    }
  },

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

  },

  /**
   * 1.页面.js文件中存放事件的回调函数的时候 存放在data的同层级下!!
   * 2.组件.js文件中存放事件的回调函数的时候 必须要存放在methods中!
   */
  methods: {
    /*
    * 1.绑定点击事件,需要在methods中绑定
    * 2.获取被点击的索引
    * 3.获取原数组
    * 4.对数组循环
    *   4.1给每一个循环项选中属性改为false
    *   4.2给当前选中项的选中属性改为true
    * */
    handleItemTap(e){
      console.log('handleItemTap')
      console.log(e.currentTarget.dataset);
      //获取被点击的索引
      const {index} = e.currentTarget.dataset;
      //点击事件触发的时候
      //触发父组件中的自定义事件,同时传递数据给 父组件
      //this.triggerEvent('父组件定义事件的名称', 要传递的参数)
      this.triggerEvent('itemChange', {index});
    }
  }
})

父组件json

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

父组件页面

<!--pages/demoComponent/demoComponent.wxml-->
<view>pages/demoComponent/demoComponent.wxml</view>
<view>1.父组件(页面)向子组件传递数据通过标签属性的方式来传递</view>
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange"></Tabs>

父组件js

// pages/demoComponent/demoComponent.js
Page({
  data: {
    tabs: [
      {
        id: 1,
        name: '首页',
        isActive: true
      }, {
        id: 2,
        name: '原创',
        isActive: false
      }, {
        id: 3,
        name: '分类',
        isActive: false
      }, {
        id: 4,
        name: '关于',
        isActive: false
      }
    ]
  },
  handleItemChange(e){
    console.log('handleItemChange')
    console.log(e)
    console.log(e.detail.index)
    const {index} = e.detail;
    let {tabs} = this.data;
    tabs.forEach((v,i)=> {
      i === index ? v.isActive = true : v.isActive = false;
    })

    this.setData({
      tabs
    })
  }
})

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值