之前看了七月老师的视频。介绍到模板的时候,七月老师说这个模板有一个缺点,大概就是封装度不够,只有页面和样式是模板化的,逻辑写不出来。这件事我也很疑惑。我今天学习了定制组件的概念,所以我尝试了一下。感觉好像弥补了模板的不足,于是写了一个小演示,也是一个笔记。
我认为
如果不需要传递参数或者向外发送事件,可以使用include,相当于直接复制布局。如果需要传递参数但不需要向外发送事件,可以使用模板。如果需要传递参数,将一些事件关联到外部,可以使用自定义组件
,这只是一个菜单组件,数据是从外部注入的。
目前还在看如何实现菜单弹出的阻尼动画效果。
代码结构如下:
menu.js
var%20%20Logger=require('./utils/Logger.js%20%20')组件({%20properties%20%20:%20{%20menu%20%20_%20list%20%20:%20Array,},data:%20{%20showMenu:%20true%20%20},attached%20%20:%20function(){%20this%20%20.%20setdata({%20menu%20%20_%20list%20%203360%20this%20%20.%20data%20%20.%20menu%20%20_%20list%20%20})},方法3360%20{//单击新建按钮一次,然后点击create%20%20tap%20%203360%20function(){%20this%20%20.%20setdata({%20showmenu%20%203360!This.data.showMenu%20%20})%20},//单击展开的单个按钮Onitetap:函数(事件){%20var%20%20item=event%20%20.%20current%20%20target%20%20.%20dataset%20%20.%20item;//在微信小程序中,信息通过triggerEvent//triggerEvent:https://developers%20%20.%20weixin%20%20.%20QQ%20%20.%20com/miniprogram/dev/framework/custom-component/Events.html%20%20menueventdail={%20item%20%20}%20this传递给父组件。触发事件('%20handle%20%20menu%20%20',menueventdail)//menueventpoption是触发事件的选项,包括设置事件是否冒泡。但是,这里的默认值是//var%20%20menueventpoption={//}/this。触发事件('%20handlemenu%20%20',menueventdetail,menueventoption)%20}})指的是文档中组件的生命周期:
p>设置数据选择在attached方法内。
查看文档
this.triggerEvent(eventName, eventDetail, eventOption)
还有个关键的地方:(其实最开始创建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" }}
传送门