纵观现代前端框架中(不论ng react vue ) 基本四架马车 声明式渲染 路由 组件化 状态管理。 反观小程序开发环境 缺失蛮多特性的 好在 11月初微信团队,发布了官方的component 化方案, 咱们基本上能够告别现有的hack办法去实现 component 化。前端
使用template实现组件化
https://zhuanlan.zhihu.com/p/...
使用include组件化
这个简单说下 include 组件wxml 和样式文件到 page 而后 ,import 组件的js文件 经过合并方式将组件data method 合并到page 对于data,直接采用 Object.assign method 进行融合,先调用组件事件,而后调用父页面事件.vue
以上方案核心: 将组件内定义的 data 和 method 合并到page中去 实现组件化, 本质上都在同一个做用域下 组件做用域没有隔离 不免会出现 命名冲突 覆盖.react
方便快速理解,下面使用官方组件化方案 实现一个模态弹窗 easyModal.git
请结合源码看 https://github.com/sherlock22... 若是以为不错请点个stargithub
阅读前 请先读通官方自定义组件文档
https://mp.weixin.qq.com/debu...json
首先分红2个小组件 来实现这个模态弹窗
基本模态弹窗 和 加强型模态弹窗小程序
基本模态弹窗 具有 前端框架
1.显示/隐藏
2.backdrop
3.过分动画
4.自定义头尾
这几部分基础功能微信
加强型模态弹窗 具有app
1.基础模态弹窗功能
2.自定义内容区域
3.title自定义
4.肯定取消按钮自定义
首先在base文件夹下直接右键建立component -> baseModal
在baseModal.js中建立组件所须要props 这些属性来自父组件或 外层page 中的数据,
Component({ options : { multipleSlots: true }, /** * 组件的属性列表 */ properties: { backdrop: { type: Boolean, value: true }, animated : { type: Boolean, value: true }, modalSize : { type: String, value: "md" }, animationOption : { type : Object, value : { duration : 300 } } }, }
下来建立 data,isShow控制 弹窗显示和隐藏 animation则是弹窗动画函数.
/** * 组件的初始数据 */ data: { isShow : false, animation : '' },
在生命周期函数 ready中初始化animation
ready: function () { this.animation = wx.createAnimation({ duration: this.data.animationOption.duration, timingFunction: "linear", delay: 0 }); },
组件有2个public方法 show hide 方法, private 有执行动画 和 切换显隐的方法
methods: { hideModal : function(e){ if(e){ let type = e.currentTarget.dataset.type; if (type == 'mask' && !this.data.backdrop) { return; } } if (this.data.isShow) this._toggleModal(); }, showModal : function(){ if (!this.data.isShow) { this._toggleModal(); } }, _toggleModal : function(){ if(!this.data.animated){ this.setData({ isShow: !this.data.isShow }) } else{ let isShow = !this.data.isShow; this._executeAnimation(isShow); } }, _executeAnimation: function (isShow) { ...... } }
能够经过animated属性来判断 组件是否须要调用_executeAnimation 来执行动画显示
页面结构
<view animation="{{animationData}}" hidden="{{!isShow}}" class='modal'> <view data-type="mask" catchtap='hideModal' class='modal-mask' ></view> <view class='modal-layer modal-layer-radius {{modalSize == "sm" ? " modal-layer-sm" : " modal-layer-md" }} ' > <!-- 头部 --> <view class='modal-header'> <slot name="header"></slot> </view> <!-- 内容区域 --> <view class='modal-body'> <slot name="body"></slot> </view> <view class='modal-footer'> <slot name="footer"></slot> </view> </view> </view>
slot 节点,用于承载组件使用者提供的wxml结构。
默认状况下,一个组件的wxml中只能有一个slot。须要使用多slot时,记得开启配置
options : { multipleSlots: true },
下来建立样式wxss
具体能够看github 文件这就不贴
/** 模态 **/ .modal{ position: fixed; top: 0rpx; left: 0rpx; right: 0rpx; bottom: 0rpx; width: 100%; height: 100%; z-index: 100; } ..............
须要注意 组件wxss文件 具有 隔离性的 你在page 中定义的class , 在app.wxss 中定义的class 都没法再组件中使用,若是真有一些须要复用到的样式 能够抽取成一个wxss 经过import 导入 组件的wxss
@import "../../style/font.wxss";
这样会增长组件和业务的耦合度 公共组件不建议使用
接下来能够在业务界面中去使用
<base-modal id="thridModal"> <view slot="header" class='modal-header'> 头部 </view> <view slot="body" class='modal-body'> 中间 </view> <view slot="footer" class='modal-footer'> 尾部 </view> </base-modal>
别忘了在业务页面的json中引入组件
{ "usingComponents": { "base-modal": "/component/easyModal/base/baseModal" } }
还记得咱们上面baseModal 有两个public方法 怎么样去调用呢 这里介绍下
Component 的一个实例方法 selectComponent
经过它 能够找到子组件实例 这个有点像是 jq 选择器 经过selector去寻找dom(可是不是dom是js对象) 不过它更像是 react 或 vue ref this.$refs.xxx 得到组件实例.
咱们给<base-modal id="thridModal">这个组件建立一个id 经过id选择器就能够找到base-modal的实例 在ready中找到modal实例
onReady: function () { this.thridModal = this.selectComponent("#thridModal"); },
而后就能够调用实例的public的方法.
this.thridModal.showModal(); this.thridModal.hideModal();
加强模态窗是基于baseModal的.
{ "component": true, "usingComponents": { "base-modal" : "../base/baseModal" } }
注意 加强模态窗口 须要包含 基本模态窗口 json中引用才能使用
<base-modal id="baseModal" modalSize="{{modalSize}}" animated="{{animated}}" backdrop="{{backdrop}}"> <view slot="header" class='modal-header'> <text>{{title}}</text> </view> <view slot="body" class='modal-body'> <slot></slot> </view> <view slot="footer" class='modal-footer'> <text catchtap='_cancelModal' class='btn btn-default'>{{cancelText}}</text> <text catchtap='_confirmModal' class='btn btn-primary'>{{confirmText}}</text> </view> </base-modal>
说下event部分 肯定 取消按钮是须要 向外部page 发送事件通知的其进行业务操做的
//cancel _cancelModal : function(){ this.hide(); this.triggerEvent("cancelEvent"); }, //success _confirmModal : function(){ this.triggerEvent("confirmEvent"); }
经过triggerEvent触发事件 这点和官网文档没有区别.
业务Page界面:
<easy-modal id="easyModal" title="这个是标题 01" bind:cancelEvent="_cancelEvent" bind:confirmEvent="_confirmEventFirst" > <view class='modal-content'> <text> 这是内容部分 01 </text> <text> 这是内容部分 01 </text> <text> 这是内容部分 01 </text> </view> </easy-modal>
一个基本模态窗口 就完成了, 知足基本业务使用 还有不少地方能够根据大家自身业务 进行 扩展.
本文原创 转载请注明署名和出处