微信小程序 自定义组件 - 弹出菜单demo

前言

以前看七月老师的视频,介绍到template的时候,七月老师说,这个template有一个缺点,大概意思就是封装度不够,只模板化了页面和样式,逻辑那些写不了。我也很困惑这件事,今天了解到自定义组件这个概念,就试了试,感受好像弥补了template的那个缺点,因而写了个小demo,也算作个笔记html

我以为git

  • 若是不须要传参,也不须要向外发送事件的,能够用include,至关于直接把布局copy过去
  • 若是须要传参,但不须要向外发送事件的,内部能够处理的,能够用template
  • 若是又须要传参,又须要向外关联一些事件的,能够使用自定义组件

自定义组件的中心思想:将页面内的功能模块抽象成自定义组件,以便在不一样的页面中重复使用;也能够将复杂的页面拆分红多个低耦合的模块,有助于代码维护github

效果

作的就是个菜单组件,数据由外部灌入。json

目前我还在看怎么样才能实现菜单弹出的阻尼动画效果小程序

image

实现

代码结构以下:微信小程序

image

新建组件menu:

image

menu.jsbash

var Logger = require('../utils/Logger.js')

Component({
 //组件暴露出去的属性
  properties: {
    //若是这里属性比较多的话,还能够将它们包裹成一个对象
    menu_list: Array,
  },

//组件内部使用的属性
  data: {
    showMenu: true
  },

  attached: function() {
    this.setData({
      menu_list: this.data.menu_list
    })
  },
  methods: {
    // 点击新建按钮
    onCreateTap: function() {
      this.setData({
        showMenu: !this.data.showMenu
      })
    },
    // 点击展开的单个按钮
    onItemTap: function(event) {
      var item = event.currentTarget.dataset.item;
      // 微信小程序中是经过triggerEvent来给父组件传递信息的
      //triggerEvent:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html
      var menuEventDetail = {
        item
      }
      this.triggerEvent('handleMenu', menuEventDetail)
      //menuEventOption是触发事件的选项,包括设置事件是否冒泡之类的,不过这里默认是不冒泡的
      // var menuEventOption = {
      //   
      // }
      // this.triggerEvent('handleMenu', menuEventDetail, menuEventOption)
    }
  }
})
复制代码

参考文档中Component的生命周期微信

image

设置数据选择在attached方法内。markdown

triggerEvent

查看文档oop

this.triggerEvent(eventName, eventDetail, eventOption)

  • eventName:事件名称
  • eventDetail:事件传递的对象,是eventName这个事件中detail属性中的内容
  • eventOption:主要定义eventName这个事件是否要冒泡之类的,不过默认的都是false,能够不用设置

image

还有个关键的地方:(其实最开始建立component的时候就自动生成了)全手打的话,要记得在menu.json里添加自定义组件的声明:

{
  "component": true,
  "usingComponents": {}
}
复制代码

menu.wxml

菜单个数根据传入的menu_list来,菜单显隐由showMenu控制

<view class='container'>
  <view hidden="{{showMenu?false:true}}" class='sub-btn-container'>
    <block wx:for='{{menu_list}}' wx:key='index'>
      <view class='sub-btns' catchtap='onItemTap' data-item='{{item}}'>
        <image class='btn' src='{{item.src}}' />
        <text class='sub-btn__name'>{{item.name}}</text>
      </view>
    </block>
  </view>
  <image catchtap='onCreateTap' class='btn' src='/resources/imgs/ic_create.png' />
</view>
复制代码

菜单的显示内容,由外部datas/menu-data.js控制

var menu_list = [{
  id: 1,
  name: '帖子',
  src: '/resources/imgs/ic_create_1.png'
}, {
  id: 2,
  name: '资讯',
  src: '/resources/imgs/ic_create_2.png'
}, {
  id: 3,
  name: '照片',
  src: '/resources/imgs/ic_create_3.png'
}]

module.exports = {
  menu_list: menu_list
}
复制代码

数据在使用的地方引入

组件的使用

home.js

var menuData = require('../../datas/menu-data.js')
var Logger = require('../../utils/Logger.js')

Page({
  onLoad: function() {
    this.setData({
      menu_list: menuData.menu_list,
    })
  },
  onReady: function() {
    this.menu = this.selectComponent("#menu");
  },
  handleMenu: function(event) {
    //这里的detail就是在自定义组件中定义的menuEventDetail
    var item = event.detail.item;
    Logger.v("item", item);
    wx.showToast({
      title: '新建' + item.name,
    })
  }
})
复制代码

home.wxml

<view>
  <!-- handleMenu为父组件和自定义组件之间通讯的桥梁 -->
  <menu class='menu' menu_list='{{menu_list}}' bind:handleMenu='handleMenu' />
  <text class='text'>HOME</text>
</view>
复制代码

还有个关键的地方:使用的地方,这里是home,要记得在home.json中使用该组件(引号前面的至关于别名,起啥名,wxml里就用啥名)

home.json

{
  "usingComponents": {
    "menu": "/components/menu"
  }
}
复制代码

传送门

相关文章
相关标签/搜索