微信小程序组件化 快速实现可用模态窗
縱觀現(xiàn)代前端框架中(不論ng react vue ) 基本四架馬車 聲明式渲染 路由 組件化 狀態(tài)管理。 反觀小程序開(kāi)發(fā)環(huán)境 缺失蠻多特性的 好在 11月初微信團(tuán)隊(duì),發(fā)布了官方的component 化方案, 我們基本上可以告別現(xiàn)有的hack辦法去實(shí)現(xiàn) component 化。
hack方式
使用template實(shí)現(xiàn)組件化 https://zhuanlan.zhihu.com/p/26785726 使用include組件化 這個(gè)簡(jiǎn)單說(shuō)下 include 組件wxml 和樣式文件到 page 然后 ,import 組件的js文件 通過(guò)合并方式將組件data method 合并到page 對(duì)于data,直接采用 Object.assign method 進(jìn)行融合,先調(diào)用組件事件,然后調(diào)用父頁(yè)面事件.
以上方案核心: 將組件內(nèi)定義的 data 和 method 合并到page中去 實(shí)現(xiàn)組件化, 本質(zhì)上都在同一個(gè)作用域下 組件作用域沒(méi)有隔離 難免會(huì)出現(xiàn) 命名沖突 覆蓋.
實(shí)現(xiàn)一個(gè)組件
方便快速理解,下面使用官方組件化方案 實(shí)現(xiàn)一個(gè)模態(tài)彈窗 easyModal.
請(qǐng)結(jié)合源碼看 https://github.com/sherlock221/wx-easyModal 如果覺(jué)得不錯(cuò)請(qǐng)點(diǎn)個(gè)star
閱讀前 請(qǐng)先讀通官方自定義組件文檔 https://mp.weixin.qq.com/debug/wxadoc/dev/framework/custom-component/
組件分析
首先分成2個(gè)小組件 來(lái)實(shí)現(xiàn)這個(gè)模態(tài)彈窗 基本模態(tài)彈窗 和 增強(qiáng)型模態(tài)彈窗
基本模態(tài)彈窗 具備
1.顯示/隱藏 2.backdrop
3.過(guò)度動(dòng)畫(huà)
4.自定義頭尾 這幾部分基礎(chǔ)功能
增強(qiáng)型模態(tài)彈窗 具備
1.基礎(chǔ)模態(tài)彈窗功能 2.自定義內(nèi)容區(qū)域 3.title自定義 4.確定取消按鈕自定義
基本模態(tài)窗
首先在base文件夾下直接右鍵創(chuàng)建component -> baseModal 在baseModal.js中創(chuàng)建組件所需要props 這些屬性來(lái)自父組件或 外層page 中的數(shù)據(jù),
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 }}}, } 復(fù)制代碼下來(lái)創(chuàng)建 data,isShow控制 彈窗顯示和隱藏 animation則是彈窗動(dòng)畫(huà)函數(shù).
/*** 組件的初始數(shù)據(jù)*/data: {isShow : false,animation : ''}, 復(fù)制代碼在生命周期函數(shù) ready中初始化animation
ready: function () { this.animation = wx.createAnimation({duration: this.data.animationOption.duration,timingFunction: "linear",delay: 0}); }, 復(fù)制代碼組件有2個(gè)public方法 show hide 方法, private 有執(zhí)行動(dòng)畫(huà) 和 切換顯隱的方法
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) {......}}復(fù)制代碼可以通過(guò)animated屬性來(lái)判斷 組件是否需要調(diào)用_executeAnimation 來(lái)執(zhí)行動(dòng)畫(huà)顯示
頁(yè)面結(jié)構(gòu)
<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><!-- 內(nèi)容區(qū)域 --><view class='modal-body'> <slot name="body"></slot> </view><view class='modal-footer'><slot name="footer"></slot> </view></view></view> 復(fù)制代碼slot 節(jié)點(diǎn),用于承載組件使用者提供的wxml結(jié)構(gòu)。 默認(rèn)情況下,一個(gè)組件的wxml中只能有一個(gè)slot。需要使用多slot時(shí),記得開(kāi)啟配置
options : {multipleSlots: true }, 復(fù)制代碼下來(lái)創(chuàng)建樣式wxss 具體可以看github 文件這就不貼
/** 模態(tài) **/ .modal{position: fixed;top: 0rpx;left: 0rpx;right: 0rpx;bottom: 0rpx;width: 100%;height: 100%; z-index: 100; } .............. 復(fù)制代碼需要注意 組件wxss文件 具備 隔離性的 你在page 中定義的class , 在app.wxss 中定義的class 都無(wú)法再組件中使用,如果真有一些需要復(fù)用到的樣式 可以抽取成一個(gè)wxss 通過(guò)import 導(dǎo)入 組件的wxss
@import "../../style/font.wxss"; 復(fù)制代碼這樣會(huì)增加組件和業(yè)務(wù)的耦合度 公共組件不建議使用
接下來(lái)可以在業(yè)務(wù)界面中去使用
<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> 復(fù)制代碼別忘了在業(yè)務(wù)頁(yè)面的json中引入組件
{ "usingComponents": { "base-modal": "/component/easyModal/base/baseModal"}} 復(fù)制代碼還記得我們上面baseModal 有兩個(gè)public方法 怎么樣去調(diào)用呢 這里介紹下
Component 的一個(gè)實(shí)例方法 selectComponent 通過(guò)它 可以找到子組件實(shí)例 這個(gè)有點(diǎn)像是 jq 選擇器 通過(guò)selector去尋找dom(但是不是dom是js對(duì)象) 不過(guò)它更像是 react 或 vue ref this.$refs.xxx 獲得組件實(shí)例.
我們給這個(gè)組件創(chuàng)建一個(gè)id 通過(guò)id選擇器就可以找到base-modal的實(shí)例 在ready中找到modal實(shí)例
onReady: function () { this.thridModal = this.selectComponent("#thridModal");}, 復(fù)制代碼然后就可以調(diào)用實(shí)例的public的方法.
this.thridModal.showModal(); this.thridModal.hideModal(); 復(fù)制代碼增強(qiáng)模態(tài)窗
增強(qiáng)模態(tài)窗是基于baseModal的.
{"component": true,"usingComponents": {"base-modal" : "../base/baseModal"} } 復(fù)制代碼注意 增強(qiáng)模態(tài)窗口 需要包含 基本模態(tài)窗口 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> 復(fù)制代碼說(shuō)下event部分 確定 取消按鈕是需要 向外部page 發(fā)送事件通知的其進(jìn)行業(yè)務(wù)操作的
//cancel_cancelModal : function(){ this.hide(); this.triggerEvent("cancelEvent");},//success_confirmModal : function(){ this.triggerEvent("confirmEvent");} 復(fù)制代碼通過(guò)triggerEvent觸發(fā)事件 這點(diǎn)和官網(wǎng)文檔沒(méi)有區(qū)別.
業(yè)務(wù)Page界面:
<easy-modal id="easyModal" title="這個(gè)是標(biāo)題 01" bind:cancelEvent="_cancelEvent" bind:confirmEvent="_confirmEventFirst" > <view class='modal-content'><text> 這是內(nèi)容部分 01 </text> <text> 這是內(nèi)容部分 01 </text> <text> 這是內(nèi)容部分 01 </text> </view> </easy-modal> 復(fù)制代碼一個(gè)基本模態(tài)窗口 就完成了, 滿足基本業(yè)務(wù)使用 還有很多地方可以根據(jù)你們自身業(yè)務(wù) 進(jìn)行 擴(kuò)展.
本文原創(chuàng) 轉(zhuǎn)載請(qǐng)注明署名和出處
轉(zhuǎn)載于:https://juejin.im/post/5a266ac951882531b15b59ad
總結(jié)
以上是生活随笔為你收集整理的微信小程序组件化 快速实现可用模态窗的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微信朋友圈:应对春节千亿访问量背后的故事
- 下一篇: 爱上MVC~ajax调用分部视图sess