简书链接:自定义组件实现对话框与自定义模板实现的比较
文章字数:693,阅读全文大约需要2分钟
自定义模板,需要导入太多配置了,并不能复用逻辑,只能复用wxml,wxss都无法复用
控制对话框显示隐藏则是使用 display:flex/none
进行切换,每一个功能都需要处理。
最后我的强迫症让我决定改成用组件实现
在根目录新建components文件夹
然后新建 compnents
命名为searchdialog
新建好之后在自己的页面 json修改
1 2 3
| "usingComponents": { "searchdialog": "/components/searchdialog" }
|
,而searchdialog
这个名字可以随便定义,这将决定了在wxml里面的命名。
···
wxml里面写入
1 2
| <searchdialog id='dialog'> </searchdialog>
|
发现正常的显示了,和模板差不多。。
完整代码
包含了类似slot,也就是 自定义view里面放入view,要放入哪里,哪个节点 则需要再模板的wxml里面定义slot
多个节点也是支持的,这里不演示。
组件wxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <view class="dialog-root-wrap" style="display:{{showSearchDialog?'flex':'none'}};"> <view class="dilog-root" bindtap="dismissDialog"> <view class="dialog-content" style="border-radius: 15rpx;min-width:60%;min-height:25%;" catchtap="_dialogAeraClick"> <view class="vertical"> <view class="input_wrap_style" id="keyword"> <input class="myinput" password type="text" placeholder="输入关键词" bindinput="bindKeywordInput" value="{{keyword}}" /> </view> <picker style="margin-top: 20rpx;" mode="date" value="{{startdate}}" start="{{initStartDate}}" end="{{initEndDate}}" bindchange="_changeDate" data-value="0"> <view class="tui-picker-detail"> 开始时间: {{startdate}} </view> </picker> <picker style="margin-top: 20rpx;" mode="date" value="{{enddate}}" start="{{initStartDate}}" end="{{initEndDate}}" bindchange="_changeDate" data-value="1"> <view class="tui-picker-detail"> 结束时间: {{enddate}} </view> </picker> <slot></slot> <button id="search" catchtap="searchClick" type="primary" style="margin-top: 30rpx;">{{confirmSearchText}}</button> </view> </view> </view> </view>
|
组件 ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| // component/searchdialog.ts import * as datefns from 'date-fns'; Component({ /** * 组件的属性列表 */ properties: { confirmSearchText: { type: String, value: '开始搜索' } },
lifetimes: { // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 created: function () { },// 无 在组件实例刚刚被创建时执行 1.6.3 attached: function () { },// 无 在组件实例进入页面节点树时执行 1.6.3 ready: function () { const date = new Date(); var lastMonth: any = datefns.subMonths(date, 1); this.setData({ initStartDate: datefns.format(datefns.subYears(date, 10), "yyyy-MM-dd"), initEndDate: datefns.format(date, "yyyy-MM-dd"), startdate: datefns.format(lastMonth, "yyyy-MM-dd"), enddate: datefns.format(date, "yyyy-MM-dd"),
});
},// 无 在组件在视图层布局完成后执行 1.6.3 moved: function () { },// 无 在组件实例被移动到节点树另一个位置时执行 1.6.3 detached: function () { },// 无 在组件实例被从页面节点树移除时执行 1.6.3 error: function () { },// Object Error 每当组件方法抛出错误时执行 2.4.1 }, /* // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 attached: function () { }, // 此处attached的声明会被lifetimes字段中的声明覆盖 ready: function () { }, */
pageLifetimes: { // 组件所在页面的生命周期函数 show: function () { }, hide: function () { }, resize: function () { }, }, /** * 组件的初始数据 */ data: { startdate: "", enddate: "", initStartDate: "", initEndDate: "", },
/** * 组件的方法列表 */ methods: { _dialogAeraClick: function () { console.debug("用于阻止点击对话框其它内容也导致隐藏的问题"); }, _changeDate(e: any) { console.debug(e); if (e.currentTarget.dataset.value == "0") { this.setData({ startdate: e.detail.value }); } else { this.setData({ enddate: e.detail.value }); } }, /* * 公有方法 */ dismissDialog: function () { this.setData({ showSearchDialog: false }) this.triggerEvent("onDismissDialog") console.debug("dismissDialogclick"); }, showDialog: function () { this.setData({ showSearchDialog: true }) this.triggerEvent("onShowDialog") }, searchClick: function () { console.debug("onSearch"); var that = this; this.triggerEvent("onSearchClick", { startdate: that.data.startdate, enddate: that.data.enddate }) }
} })
|
page中的实现
···
onShowDialog(e: any) {
console.debug(“收到了组件传递的onShowDialog事件 “);
},
onDismissDialog(e: any) {
console.debug(“收到了组件传递的onDismissDialog事件 “);
},
requestShowDialog() {
var dialog = this.selectComponent(“#dialog”);
dialog.showDialog();
},
onSearchClick(e: any) {
console.debug(“收到了组件的onSearchClick “, e, e.detail.startdate, e.detail.enddate);
},
···
page wxml的引用参数和定义事件监听
1 2
| <searchdialog id='dialog' confirmSearchText='确认搜索' bind:onDismissDialog="onDismissDialog" bind:onShowDialog="onShowDialog" bind:onSearchClick="onSearchClick"> </searchdialog>
|
原理就是再组件的事件里面使用 this.triggerEvent("onShowDialog")
分发事件,
在page wxml使用bind
即可, 对于多个参数的接受
1
| this.triggerEvent("onSearchClick", { startdate: that.data.startdate, enddate: that.data.enddate })
|
page中的定义
1 2 3
| onSearchClick(e: any) { console.debug("收到了组件的onSearchClick ", e, e.detail.startdate, e.detail.enddate); },
|
到这里已经实现完了对话框的弹出监听,以及搜索接受参数,已经page界面控制显示隐藏
properties
为对外暴露的字段,