縱觀現代前端框架中(不論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>
一個基本模態窗口 就完成了, 知足基本業務使用 還有不少地方能夠根據大家自身業務 進行 擴展.
本文原創 轉載請註明署名和出處